1 #Region "Microsoft.VisualBasic::d43601ef4659ad20a084b2489beb004e, Microsoft.VisualBasic.Core\ComponentModel\Settings\Inf\ClassMapper.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class ClassName
35     
36     '         Properties: Name
37     
38     '         Constructor: (+1 OverloadsSub New
39     '         FunctionToString
40     
41     '     Module ClassMapper
42     
43     '         Function: (+2 OverloadsClassWriter, LoadIni, (+2 Overloads) MapParser, WriteClass
44     
45     '         Sub: (+2 OverloadsClassDumper
46     
47     
48     ' /********************************************************************************/
49
50 #End Region
51
52 Imports System.Runtime.CompilerServices
53 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
54 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel.SchemaMaps
55 Imports Microsoft.VisualBasic.Linq
56
57 Namespace ComponentModel.Settings.Inf
58
59     ''' <summary>
60     ''' 定义在Ini配置文件之中的Section的名称
61     ''' </summary>
62     <AttributeUsage(AttributeTargets.Class, AllowMultiple:=False, Inherited:=True)>
63     Public Class ClassName : Inherits Attribute
64
65         Public ReadOnly Property Name As String
66
67         ''' <summary>
68         ''' Defines the section name in the ini profile data.(定义在Ini配置文件之中的Section的名称)
69         ''' </summary>
70         ''' <param name="name"></param>
71         Sub New(name As String)
72             Me.Name = name
73         End Sub
74
75         Public Overrides Function ToString() As String
76             Return Name
77         End Function
78     End Class
79
80     ''' <summary>
81     ''' 使用这个属性来标记需要进行序列化的对象属性: <see cref="DataFrameColumnAttribute"/>
82     ''' </summary>
83     Public Module ClassMapper
84
85         <MethodImpl(MethodImplOptions.AggressiveInlining)>
86         Public Function MapParser(Of T As Class)() As NamedValue(Of BindProperty(Of DataFrameColumnAttribute)())
87             Return GetType(T).MapParser
88         End Function
89
90         ''' <summary>
91         ''' Get mapping data, includes section name and keys
92         ''' </summary>
93         ''' <param name="type"></param>
94         ''' <returns></returns>
95         <Extension>
96         Public Function MapParser(type As Type) As NamedValue(Of BindProperty(Of DataFrameColumnAttribute)())
97             Dim nameCLS As ClassName = type.GetAttribute(Of ClassName)
98             Dim name As String
99
100             If nameCLS Is Nothing Then
101                 name = type.Name
102             Else
103                 name = nameCLS.Name
104             End If
105
106             Dim source = DataFrameColumnAttribute.LoadMapping(type)
107             Dim binds As BindProperty(Of DataFrameColumnAttribute)() =
108                 source.Values.ToArray
109
110             Return New NamedValue(Of BindProperty(Of DataFrameColumnAttribute)()) With {
111                 .Name = name,
112                 .Value = binds
113             }
114         End Function
115
116         ''' <summary>
117         ''' Read data from ini file.
118         ''' </summary>
119         ''' <typeparam name="T"></typeparam>
120         ''' <param name="ini"></param>
121         ''' <returns></returns>
122         ''' 
123         <Extension>
124         Public Function ClassWriter(Of T As {New, Class})(ini As IniFile) As T
125             Return DirectCast(ClassWriter(ini, GetType(T)), T)
126         End Function
127
128         Public Function ClassWriter(ini As IniFile, type As Type) As Object
129             Dim obj As Object = Activator.CreateInstance(type)
130             Dim maps = MapParser(type)
131
132             For Each map In maps.Value
133                 Dim key As String = map.field.Name
134                 Dim value As String = ini.ReadValue(maps.Name, key)
135                 Dim o As Object = Scripting.CTypeDynamic(value, map.Type)
136                 Call map.SetValue(obj, o)
137             Next
138
139             Return obj
140         End Function
141
142         <MethodImpl(MethodImplOptions.AggressiveInlining)>
143         <Extension>
144         Public Sub ClassDumper(Of T As Class)(x As T, ini As IniFile)
145             Call ClassDumper(x, GetType(T), ini)
146         End Sub
147
148         Public Sub ClassDumper(x As Object, type As Type, ini As IniFile)
149             Dim maps = MapParser(type)
150
151             For Each map In maps.Value
152                 Dim key As String = map.field.Name
153                 Dim value As String = Scripting.ToString(map.GetValue(x))
154                 Call ini.WriteValue(maps.Name, key, value)
155             Next
156         End Sub
157
158         ''' <summary>
159         ''' Load a ini section profile data from a ini file.
160         ''' </summary>
161         ''' <typeparam name="T">The section mapper</typeparam>
162         ''' <param name="path">*.ini file</param>
163         ''' <returns></returns>
164         ''' 
165         <MethodImpl(MethodImplOptions.AggressiveInlining)>
166         <Extension>
167         Public Function LoadIni(Of T As {New, Class})(path As StringAs T
168             Return New IniFile(path).ClassWriter(Of T)
169         End Function
170
171         ''' <summary>
172         ''' Write ini section into data file.
173         ''' </summary>
174         ''' <typeparam name="T"></typeparam>
175         ''' <param name="x">A section class in the ini profile file.</param>
176         ''' <param name="ini"></param>
177         ''' <returns></returns>
178         <Extension>
179         Public Function WriteClass(Of T As Class)(x As T, ini As StringAs Boolean
180             Try
181                 Call x.ClassDumper(New IniFile(ini))
182             Catch ex As Exception
183                 ex = New Exception(ini, ex)
184                 ex = New Exception(GetType(T).FullName, ex)
185                 Call ex.PrintException
186                 Call App.LogException(ex)
187                 Return False
188             End Try
189
190             Return True
191         End Function
192     End Module
193 End Namespace