1
+ using Cosmos . DataTransfer . Interfaces ;
2
+ using Cosmos . DataTransfer . Interfaces . Manifest ;
3
+ using Microsoft . Extensions . Logging ;
4
+ using System ;
5
+ using System . ComponentModel . Composition . Hosting ;
6
+ using System . Reflection ;
7
+
8
+ namespace Cosmos . DataTransfer . Core
9
+ {
10
+ public class ExtensionManifestBuilder : IExtensionManifestBuilder
11
+ {
12
+ private readonly ILogger _logger ;
13
+ private readonly IExtensionLoader _extensionLoader ;
14
+
15
+ public ExtensionManifestBuilder ( IExtensionLoader extensionLoader , ILogger < ExtensionManifestBuilder > logger )
16
+ {
17
+ _extensionLoader = extensionLoader ;
18
+ _logger = logger ;
19
+ }
20
+
21
+ public List < IDataSourceExtension > GetSources ( )
22
+ {
23
+ string extensionsPath = _extensionLoader . GetExtensionFolderPath ( ) ;
24
+ CompositionContainer container = _extensionLoader . BuildExtensionCatalog ( extensionsPath ) ;
25
+
26
+ return _extensionLoader . LoadExtensions < IDataSourceExtension > ( container ) ;
27
+ }
28
+
29
+ public List < IDataSinkExtension > GetSinks ( )
30
+ {
31
+ string extensionsPath = _extensionLoader . GetExtensionFolderPath ( ) ;
32
+ CompositionContainer container = _extensionLoader . BuildExtensionCatalog ( extensionsPath ) ;
33
+
34
+ return _extensionLoader . LoadExtensions < IDataSinkExtension > ( container ) ;
35
+ }
36
+
37
+ public ExtensionManifest BuildManifest ( ExtensionDirection direction )
38
+ {
39
+ var extensions = new List < IDataTransferExtension > ( ) ;
40
+ if ( direction == ExtensionDirection . Source )
41
+ {
42
+ extensions . AddRange ( GetSources ( ) ) ;
43
+ }
44
+ else
45
+ {
46
+ extensions . AddRange ( GetSinks ( ) ) ;
47
+ }
48
+ var manifest = new ExtensionManifest ( extensions
49
+ . Select ( e => new ExtensionManifestItem ( e . DisplayName ,
50
+ direction ,
51
+ GetExtensionSettings ( e as IExtensionWithSettings ) ) ) . ToList ( ) ) ;
52
+ return manifest ;
53
+ }
54
+
55
+ public List < ExtensionSettingProperty > GetExtensionSettings ( IExtensionWithSettings ? extension )
56
+ {
57
+ var allProperties = new List < ExtensionSettingProperty > ( ) ;
58
+ if ( extension != null )
59
+ {
60
+ var allSettings = extension . GetSettings ( ) ;
61
+ foreach ( IDataExtensionSettings settings in allSettings )
62
+ {
63
+ var settingsType = settings . GetType ( ) ;
64
+
65
+ var props = settingsType . GetProperties ( ) ;
66
+ foreach ( PropertyInfo propertyInfo in props )
67
+ {
68
+ var defaultValue = propertyInfo . GetValue ( settings ) ;
69
+ var settingProperty = new ExtensionSettingProperty ( propertyInfo . Name , GetPropertyType ( propertyInfo . PropertyType ) )
70
+ {
71
+ IsRequired = propertyInfo . GetCustomAttribute < System . ComponentModel . DataAnnotations . RequiredAttribute > ( ) is not null ,
72
+ DefaultValue = defaultValue ,
73
+ IsSensitive = propertyInfo . GetCustomAttribute < SensitiveValueAttribute > ( ) is not null
74
+ } ;
75
+ if ( settingProperty . Type == PropertyType . Enum )
76
+ {
77
+ settingProperty . ValidValues . AddRange ( GetPropertyEnumValues ( propertyInfo , settings ) ) ;
78
+ }
79
+ allProperties . Add ( settingProperty ) ;
80
+ }
81
+ }
82
+ }
83
+
84
+ return allProperties ;
85
+ }
86
+
87
+ private IEnumerable < string > GetPropertyEnumValues ( PropertyInfo propertyInfo , IDataExtensionSettings settings )
88
+ {
89
+ if ( propertyInfo . PropertyType . IsEnum )
90
+ {
91
+ return Enum . GetNames ( propertyInfo . PropertyType ) ;
92
+ }
93
+
94
+ return Enumerable . Empty < string > ( ) ;
95
+ }
96
+
97
+ private static PropertyType GetPropertyType ( Type type )
98
+ {
99
+ if ( type . IsGenericType && type . GetGenericTypeDefinition ( ) == typeof ( Nullable < > ) )
100
+ {
101
+ var genericType = type . GetGenericArguments ( ) . FirstOrDefault ( ) ;
102
+ if ( genericType != null )
103
+ type = genericType ;
104
+ }
105
+
106
+ if ( type == typeof ( byte ) || type == typeof ( short ) || type == typeof ( ushort ) ||
107
+ type == typeof ( int ) || type == typeof ( uint ) ||
108
+ type == typeof ( long ) || type == typeof ( ulong ) )
109
+ {
110
+ return PropertyType . Int ;
111
+ }
112
+
113
+ if ( type == typeof ( double ) || type == typeof ( float ) || type == typeof ( decimal ) )
114
+ {
115
+ return PropertyType . Float ;
116
+ }
117
+
118
+ if ( type == typeof ( bool ) )
119
+ {
120
+ return PropertyType . Boolean ;
121
+ }
122
+
123
+ if ( type == typeof ( DateTime ) || type == typeof ( DateTimeOffset ) )
124
+ {
125
+ return PropertyType . DateTime ;
126
+ }
127
+
128
+ if ( type . IsEnum )
129
+ {
130
+ return PropertyType . Enum ;
131
+ }
132
+
133
+ return PropertyType . String ;
134
+ }
135
+ }
136
+ }
0 commit comments