11using FlowSynx . PluginCore ;
22using FlowSynx . PluginCore . Extensions ;
3- using FlowSynx . PluginCore . Helpers ;
43using FlowSynx . Plugins . Json . Models ;
4+ using FlowSynx . Plugins . Json . Services ;
55using Newtonsoft . Json . Linq ;
66
77namespace FlowSynx . Plugins . Json ;
88
99public class JsonPlugin : IPlugin
1010{
11+ private readonly IGuidProvider _guidProvider ;
12+ private readonly IReflectionGuard _reflectionGuard ;
1113 private IPluginLogger ? _logger ;
1214 private bool _isInitialized ;
1315
14- public PluginMetadata Metadata
16+ public JsonPlugin ( ) : this ( new GuidProvider ( ) , new DefaultReflectionGuard ( ) ) { }
17+
18+ internal JsonPlugin ( IGuidProvider guidProvider , IReflectionGuard reflectionGuard )
1519 {
16- get
17- {
18- return new PluginMetadata
19- {
20- Id = Guid . Parse ( "61519421-6eb9-466b-aaed-366098da1922" ) ,
21- Name = "Json" ,
22- CompanyName = "FlowSynx" ,
23- Description = Resources . PluginDescription ,
24- Version = new PluginVersion ( 1 , 0 , 0 ) ,
25- Category = PluginCategory . Data ,
26- Authors = new List < string > { "FlowSynx" } ,
27- Copyright = "© FlowSynx. All rights reserved." ,
28- Icon = "flowsynx.png" ,
29- ReadMe = "README.md" ,
30- RepositoryUrl = "https://github.com/flowsynx/plugin-json" ,
31- ProjectUrl = "https://flowsynx.io" ,
32- Tags = new List < string > ( ) { "flowSynx" , "json" , "data" , "data-platform" }
33- } ;
34- }
20+ _guidProvider = guidProvider ?? throw new ArgumentNullException ( nameof ( guidProvider ) ) ;
21+ _reflectionGuard = reflectionGuard ?? throw new ArgumentNullException ( nameof ( reflectionGuard ) ) ;
3522 }
3623
24+ public PluginMetadata Metadata => new ( )
25+ {
26+ Id = Guid . Parse ( "61519421-6eb9-466b-aaed-366098da1922" ) ,
27+ Name = "Json" ,
28+ CompanyName = "FlowSynx" ,
29+ Description = Resources . PluginDescription ,
30+ Version = new PluginVersion ( 1 , 0 , 0 ) ,
31+ Category = PluginCategory . Data ,
32+ Authors = new List < string > { "FlowSynx" } ,
33+ Copyright = "© FlowSynx. All rights reserved." ,
34+ Icon = "flowsynx.png" ,
35+ ReadMe = "README.md" ,
36+ RepositoryUrl = "https://github.com/flowsynx/plugin-json" ,
37+ ProjectUrl = "https://flowsynx.io" ,
38+ Tags = new List < string > ( ) { "flowSynx" , "json" , "data" , "data-platform" }
39+ } ;
40+
3741 public PluginSpecifications ? Specifications { get ; set ; }
3842
3943 public Type SpecificationsType => typeof ( JsonPluginSpecifications ) ;
4044
41- private Dictionary < string , Func < JObject , InputParameter , object > > OperationMap => new ( StringComparer . OrdinalIgnoreCase )
45+ private Dictionary < string , IJsonOperationHandler > OperationMap => new ( StringComparer . OrdinalIgnoreCase )
4246 {
43- [ "extract" ] = HandleExtract ,
44- [ "map" ] = HandleMap ,
45- [ "transform" ] = HandleTransform
47+ [ "extract" ] = new ExtractOperationHandler ( _guidProvider ) ,
48+ [ "map" ] = new MapOperationHandler ( _guidProvider ) ,
49+ [ "transform" ] = new TransformOperationHandler ( _guidProvider )
4650 } ;
4751
48- public IReadOnlyCollection < string > SupportedOperations => new [ ] { "extract" , "map" , "transform" } ;
52+ public IReadOnlyCollection < string > SupportedOperations => OperationMap . Keys ;
4953
5054 public Task Initialize ( IPluginLogger logger )
5155 {
52- if ( ReflectionHelper . IsCalledViaReflection ( ) )
56+ if ( _reflectionGuard . IsCalledViaReflection ( ) )
5357 throw new InvalidOperationException ( Resources . ReflectionBasedAccessIsNotAllowed ) ;
5458
5559 ArgumentNullException . ThrowIfNull ( logger ) ;
@@ -58,79 +62,40 @@ public Task Initialize(IPluginLogger logger)
5862 return Task . CompletedTask ;
5963 }
6064
61- public async Task < object ? > ExecuteAsync ( PluginParameters parameters , CancellationToken cancellationToken )
65+ public Task < object ? > ExecuteAsync ( PluginParameters parameters , CancellationToken cancellationToken )
6266 {
63- if ( ReflectionHelper . IsCalledViaReflection ( ) )
67+ cancellationToken . ThrowIfCancellationRequested ( ) ;
68+
69+ if ( _reflectionGuard . IsCalledViaReflection ( ) )
6470 throw new InvalidOperationException ( Resources . ReflectionBasedAccessIsNotAllowed ) ;
6571
6672 if ( ! _isInitialized )
6773 throw new InvalidOperationException ( $ "Plugin '{ Metadata . Name } ' v{ Metadata . Version } is not initialized.") ;
6874
6975 var inputParameter = parameters . ToObject < InputParameter > ( ) ;
70- var operation = inputParameter . Operation ;
71-
72- if ( OperationMap . TryGetValue ( operation , out var handler ) )
73- {
74- var json = inputParameter . Json ?? throw new ArgumentException ( "Input JSON is required." ) ;
75- var jsonObj = JObject . Parse ( json ) ;
76-
77- return handler ( jsonObj , inputParameter ) ;
78- }
79-
80- throw new NotSupportedException ( $ "Json plugin: Operation '{ operation } ' is not supported.") ;
81- }
82-
83- private object HandleExtract ( JObject json , InputParameter inputParameter )
84- {
85- string ? path = inputParameter . jsonPath ;
86- if ( string . IsNullOrWhiteSpace ( path ) )
87- throw new ArgumentException ( "jsonPath parameter is required for extract." ) ;
88-
89- var token = json . SelectToken ( path ) ;
90- return token ? . ToString ( ) ?? "null" ;
91- }
92-
93- private object HandleMap ( JObject json , InputParameter inputParameter )
94- {
95- if ( inputParameter . Mappings == null )
96- throw new InvalidOperationException ( "Mappings not defined in specifications." ) ;
97-
98- var result = new Dictionary < string , object ? > ( ) ;
99- foreach ( var kvp in inputParameter . Mappings )
76+ if ( ! OperationMap . TryGetValue ( inputParameter . Operation , out var handler ) )
10077 {
101- result [ kvp . Key ] = json . SelectToken ( kvp . Value ) ? . ToString ( ) ;
78+ throw new NotSupportedException ( $ "Operation ' { inputParameter . Operation } ' is not supported." ) ;
10279 }
10380
104- return result ;
105- }
106-
107- private object HandleTransform ( JObject json , InputParameter inputParameter )
108- {
109- var result = json ;
81+ var context = ParseDataToContext ( inputParameter . Data ) ;
82+ var json = context . Content ?? throw new ArgumentException ( "Input JSON is required." ) ;
11083
111- if ( inputParameter . Flatten )
112- result = FlattenJson ( json ) ;
113-
114- return result ;
84+ var jsonToken = JToken . Parse ( json ) ;
85+ return Task . FromResult ( handler . Handle ( jsonToken , inputParameter ) ) ;
11586 }
11687
117- private JObject FlattenJson ( JObject input )
88+ private PluginContext ParseDataToContext ( object ? data )
11889 {
119- var result = new JObject ( ) ;
90+ if ( data is null )
91+ throw new ArgumentNullException ( nameof ( data ) , "Input data cannot be null." ) ;
12092
121- void Flatten ( JObject obj , string prefix )
93+ return data switch
12294 {
123- foreach ( var prop in obj . Properties ( ) )
124- {
125- var path = string . IsNullOrEmpty ( prefix ) ? prop . Name : $ "{ prefix } .{ prop . Name } ";
126- if ( prop . Value is JObject nested )
127- Flatten ( nested , path ) ;
128- else
129- result [ path ] = prop . Value ;
130- }
131- }
132-
133- Flatten ( input , "" ) ;
134- return result ;
95+ PluginContext singleContext => singleContext ,
96+ IEnumerable < PluginContext > => throw new NotSupportedException ( "List of PluginContext is not supported." ) ,
97+ string strData => new PluginContext ( _guidProvider . NewGuid ( ) . ToString ( ) , "Data" ) { Content = strData } ,
98+ _ => throw new NotSupportedException ( "Unsupported input data format." )
99+ } ;
135100 }
136101}
0 commit comments