1+ package com .relogiclabs .jschema .internal .loader ;
2+
3+ import com .relogiclabs .jschema .exception .ClassInstantiationException ;
4+ import com .relogiclabs .jschema .exception .InvalidImportException ;
5+ import com .relogiclabs .jschema .extension .ConstraintFunction ;
6+ import com .relogiclabs .jschema .extension .ConstraintFunctions ;
7+ import com .relogiclabs .jschema .extension .InvokableNative ;
8+ import com .relogiclabs .jschema .extension .ScriptFunction ;
9+ import com .relogiclabs .jschema .extension .ScriptFunctions ;
10+ import com .relogiclabs .jschema .extension .ScriptMethod ;
11+ import com .relogiclabs .jschema .extension .ScriptMethods ;
12+ import lombok .Getter ;
13+
14+ import java .lang .reflect .InvocationTargetException ;
15+
16+ import static com .relogiclabs .jschema .message .ErrorCode .IMPLOD01 ;
17+ import static com .relogiclabs .jschema .message .ErrorCode .IMPLOD02 ;
18+ import static com .relogiclabs .jschema .message .ErrorCode .IMPLOD03 ;
19+ import static com .relogiclabs .jschema .message .ErrorCode .IMPLOD04 ;
20+ import static com .relogiclabs .jschema .message .ErrorCode .INSTCR01 ;
21+ import static com .relogiclabs .jschema .message .ErrorCode .INSTCR02 ;
22+ import static com .relogiclabs .jschema .message .ErrorCode .INSTCR03 ;
23+ import static com .relogiclabs .jschema .message .ErrorCode .INSTCR04 ;
24+
25+ @ Getter
26+ public class ImportLoader {
27+ private final ConstraintStorage constraints ;
28+ private final ScriptStorage scripts ;
29+
30+ public ImportLoader (ConstraintStorage constraints , ScriptStorage scripts ) {
31+ this .constraints = constraints ;
32+ this .scripts = scripts ;
33+ }
34+
35+ public InvokableNative load (Class <?> module ) {
36+ var instance = createInstance (module );
37+ for (var method : module .getMethods ()) {
38+ var constraintFunction = method .getAnnotation (ConstraintFunction .class );
39+ if (constraintFunction != null ) {
40+ if (!(instance instanceof ConstraintFunctions ins ))
41+ throw failOnNotImplement (IMPLOD02 , ConstraintFunctions .class , module );
42+ constraints .addFunction (new NativeSchemaFunction (method , constraintFunction , ins ));
43+ }
44+ var scriptFunction = method .getAnnotation (ScriptFunction .class );
45+ if (scriptFunction != null ) {
46+ if (!(instance instanceof ScriptFunctions ins ))
47+ throw failOnNotImplement (IMPLOD03 , ScriptFunctions .class , module );
48+ scripts .addFunction (new ScriptFunctionWrapper (method , scriptFunction , ins ));
49+ }
50+ var scriptMethod = method .getAnnotation (ScriptMethod .class );
51+ if (scriptMethod != null ) {
52+ if (!(instance instanceof ScriptMethods ins ))
53+ throw failOnNotImplement (IMPLOD04 , ScriptMethods .class , module );
54+ scripts .addMethod (new ScriptMethodWrapper (method , scriptMethod , ins ));
55+ }
56+ }
57+ return instance ;
58+ }
59+
60+ private static InvokableNative createInstance (Class <?> module ) {
61+ Object instance ;
62+ try {
63+ instance = module .getDeclaredConstructor ().newInstance ();
64+ } catch (NoSuchMethodException e ) {
65+ throw failOnCreateInstance (INSTCR01 , e , module );
66+ } catch (InstantiationException e ) {
67+ throw failOnCreateInstance (INSTCR02 , e , module );
68+ } catch (InvocationTargetException e ) {
69+ throw failOnCreateInstance (INSTCR03 , e , module );
70+ } catch (IllegalAccessException e ) {
71+ throw failOnCreateInstance (INSTCR04 , e , module );
72+ }
73+ if (!(instance instanceof InvokableNative result ))
74+ throw failOnNotImplement (IMPLOD01 , InvokableNative .class , module );
75+ return result ;
76+ }
77+
78+ private static RuntimeException failOnNotImplement (String code , Class <?> type , Class <?> module ) {
79+ return new InvalidImportException (code , module + " not implements " + type );
80+ }
81+
82+ private static RuntimeException failOnCreateInstance (String code , Exception ex , Class <?> module ) {
83+ return new ClassInstantiationException (code , "Fail to create an instance of " + module , ex );
84+ }
85+ }
0 commit comments