├── .gitignore
├── pom.xml
├── readme.md
└── src
├── main
├── java
│ └── com
│ │ └── github
│ │ └── middleware
│ │ └── fsm
│ │ ├── builder
│ │ ├── StateMachine.java
│ │ ├── StateMachines.java
│ │ ├── chain
│ │ │ ├── From.java
│ │ │ ├── LocalTransitionBuilder.java
│ │ │ ├── On.java
│ │ │ ├── To.java
│ │ │ ├── TransitionActivity.java
│ │ │ ├── TransitionCriteria.java
│ │ │ ├── TransitionDefine.java
│ │ │ ├── When.java
│ │ │ ├── dto
│ │ │ │ └── TransitionResult.java
│ │ │ └── support
│ │ │ │ ├── LocalTransitionBuilderImpl.java
│ │ │ │ └── TransitionImpl.java
│ │ ├── event
│ │ │ ├── ActionEvent.java
│ │ │ ├── AfterExecActionEvent.java
│ │ │ ├── AfterExecActionListener.java
│ │ │ ├── AsyncEventListener.java
│ │ │ ├── BaseEvent.java
│ │ │ ├── BaseListener.java
│ │ │ ├── BeforeExecActionEvent.java
│ │ │ ├── BeforeExecActionListener.java
│ │ │ ├── EventType.java
│ │ │ ├── ExecActionExceptionEvent.java
│ │ │ ├── ExecActionExceptionListener.java
│ │ │ ├── ListenerMapping.java
│ │ │ ├── StateMachineEvent.java
│ │ │ ├── TransitionBeginEvent.java
│ │ │ ├── TransitionBeginListener.java
│ │ │ ├── TransitionCompleteEvent.java
│ │ │ ├── TransitionCompleteListener.java
│ │ │ ├── TransitionDeclinedEvent.java
│ │ │ ├── TransitionDeclinedListener.java
│ │ │ ├── TransitionEndEvent.java
│ │ │ ├── TransitionEndListener.java
│ │ │ ├── TransitionEvent.java
│ │ │ ├── TransitionExceptionEvent.java
│ │ │ ├── TransitionExceptionListener.java
│ │ │ ├── annotation
│ │ │ │ ├── AsyncExec.java
│ │ │ │ ├── ListenerOrder.java
│ │ │ │ ├── OnActionException.java
│ │ │ │ ├── OnAfterAction.java
│ │ │ │ ├── OnBeforeAction.java
│ │ │ │ ├── OnTransitionBegin.java
│ │ │ │ ├── OnTransitionComplete.java
│ │ │ │ ├── OnTransitionDecline.java
│ │ │ │ ├── OnTransitionEnd.java
│ │ │ │ └── OnTransitionException.java
│ │ │ ├── dto
│ │ │ │ ├── ListenerMappingContext.java
│ │ │ │ ├── ListenerMappingContextItem.java
│ │ │ │ └── ListenerMethod.java
│ │ │ └── support
│ │ │ │ ├── AbstractExecActionEvent.java
│ │ │ │ ├── AbstractStateMachineEvent.java
│ │ │ │ ├── AbstractTransitionEvent.java
│ │ │ │ ├── AfterExecActionEventImpl.java
│ │ │ │ ├── BeforeExecActionEventImpl.java
│ │ │ │ ├── ExecActionExceptionEventImpl.java
│ │ │ │ ├── TransitionBeginEventImpl.java
│ │ │ │ ├── TransitionCompleteEventImpl.java
│ │ │ │ ├── TransitionDeclinedEventImpl.java
│ │ │ │ ├── TransitionEndEventImpl.java
│ │ │ │ └── TransitionExceptionEventImpl.java
│ │ ├── exec
│ │ │ ├── Action.java
│ │ │ ├── ActionExecService.java
│ │ │ ├── EntryExitBuilder.java
│ │ │ ├── annotation
│ │ │ │ └── ExecWhen.java
│ │ │ ├── dto
│ │ │ │ ├── ExecServiceContext.java
│ │ │ │ ├── RegularTransition.java
│ │ │ │ └── RuleExecContext.java
│ │ │ └── support
│ │ │ │ ├── AbstractAction.java
│ │ │ │ ├── AbstractExecService.java
│ │ │ │ ├── ActionExecServiceImpl.java
│ │ │ │ ├── ActionImpl.java
│ │ │ │ ├── ActionWrapper.java
│ │ │ │ ├── EntryExitBuilderImpl.java
│ │ │ │ ├── MethodCallImpl.java
│ │ │ │ └── MethodCallProxyImpl.java
│ │ ├── machine
│ │ │ ├── StateMachineBuilder.java
│ │ │ ├── annotation
│ │ │ │ └── HoldPayload.java
│ │ │ ├── dto
│ │ │ │ ├── RequestPayload.java
│ │ │ │ ├── StateMachineContext.java
│ │ │ │ └── StateMachineData.java
│ │ │ ├── factroy
│ │ │ │ └── StateMachineBuilderFactory.java
│ │ │ └── support
│ │ │ │ ├── AbstractStateMachine.java
│ │ │ │ ├── AbstractSubject.java
│ │ │ │ ├── StateMachineBuilderImpl.java
│ │ │ │ └── visit
│ │ │ │ ├── AbstractStateMachineProxy.java
│ │ │ │ ├── DefaultStateMachineBuilder.java
│ │ │ │ ├── StateMachineBuilderProxy.java
│ │ │ │ └── StateMachineProxy.java
│ │ ├── plugin
│ │ │ ├── PluginBuilder.java
│ │ │ ├── PluginLiftcycle.java
│ │ │ ├── PluginProvider.java
│ │ │ ├── log
│ │ │ │ ├── LogExec.java
│ │ │ │ └── support
│ │ │ │ │ └── FsmListenerLogger.java
│ │ │ └── support
│ │ │ │ ├── AbstractPluginProvider.java
│ │ │ │ └── PluginBuilderImpl.java
│ │ ├── selector
│ │ │ ├── QueueStrategy.java
│ │ │ ├── ReentrantLockStrategy.java
│ │ │ ├── SingleStrategy.java
│ │ │ └── StateMachineStrategy.java
│ │ └── state
│ │ │ ├── ImmutableLinkedState.java
│ │ │ ├── StateActivity.java
│ │ │ ├── StateCriteria.java
│ │ │ ├── StateDefine.java
│ │ │ ├── StateLiftcycle.java
│ │ │ ├── dto
│ │ │ └── StateContext.java
│ │ │ └── support
│ │ │ ├── AbstractState.java
│ │ │ ├── ChoiceStateDefine.java
│ │ │ ├── SimpleStateDefine.java
│ │ │ ├── StateImpl.java
│ │ │ └── visit
│ │ │ └── ProxyStateDefine.java
│ │ ├── config
│ │ ├── annotation
│ │ │ ├── State.java
│ │ │ ├── StateMachineParameters.java
│ │ │ ├── States.java
│ │ │ ├── Transition.java
│ │ │ └── Transitions.java
│ │ ├── application
│ │ │ ├── AbstractConfig.java
│ │ │ └── StateMachineConfig.java
│ │ └── loader
│ │ │ ├── AnnotationResovler.java
│ │ │ └── support
│ │ │ ├── AnnotationResovlerImpl.java
│ │ │ ├── AntrlStateLoader.java
│ │ │ └── XmlStateLoader.java
│ │ ├── core
│ │ ├── Singletonable.java
│ │ ├── Version.java
│ │ ├── convert
│ │ │ ├── Converter.java
│ │ │ ├── ConverterProvider.java
│ │ │ ├── PayloadParse.java
│ │ │ └── support
│ │ │ │ ├── ConverterImpl.java
│ │ │ │ └── ConverterProviderImpl.java
│ │ ├── el
│ │ │ ├── Dsl.java
│ │ │ ├── MvelScriptManager.java
│ │ │ └── support
│ │ │ │ └── MvelScriptManagerImpl.java
│ │ ├── extension
│ │ │ └── SPI.java
│ │ ├── factory
│ │ │ ├── DependProvider.java
│ │ │ ├── SingletonProviderFactory.java
│ │ │ └── ThreadExecutorService.java
│ │ ├── types
│ │ │ ├── ProcessingQueue.java
│ │ │ └── TypeReference.java
│ │ └── utils
│ │ │ ├── IDProvider.java
│ │ │ ├── JsonUtil.java
│ │ │ ├── Precondition.java
│ │ │ ├── ReflectUtil.java
│ │ │ └── StringUtil.java
│ │ ├── exception
│ │ ├── ApiObsoleteException.java
│ │ ├── ErrorCode.java
│ │ ├── EventAlreadyExistsException.java
│ │ ├── EventNotDefinedException.java
│ │ ├── IllegalAnnotationException.java
│ │ ├── IllegalPreCheckerException.java
│ │ ├── NotPayloadException.java
│ │ ├── NotSuchEventException.java
│ │ ├── NotSuchStateException.java
│ │ ├── NotSupportedException.java
│ │ ├── SateAlreadyExistsException.java
│ │ ├── StateMachineException.java
│ │ └── StateNotDefinedException.java
│ │ ├── filter
│ │ ├── annotation
│ │ │ └── PostConstruct.java
│ │ ├── validator
│ │ │ ├── PreChecker.java
│ │ │ └── support
│ │ │ │ ├── AbstractPreChecker.java
│ │ │ │ ├── MvelCheckerImpl.java
│ │ │ │ └── PreCheckers.java
│ │ └── wrapper
│ │ │ ├── ComposPostProcessor.java
│ │ │ ├── PostProcessor.java
│ │ │ ├── PostProcessorProvider.java
│ │ │ └── support
│ │ │ ├── ComposPostProcessorImpl.java
│ │ │ └── PostConstructPostProcessorImpl.java
│ │ └── spring
│ │ ├── StatemachineBuilderSupport.java
│ │ ├── StatemachineFactoryBean.java
│ │ ├── StatemachineScannerConfigurer.java
│ │ └── annotation
│ │ └── StatemachineService.java
└── resources
│ ├── images
│ └── thread.jpg
│ └── logback.xml
└── test
├── java
└── com
│ └── github
│ └── middleware
│ └── fsm
│ ├── builder
│ ├── AnnotationResovler_test.java
│ ├── Performance_Test.java
│ └── dto
│ │ └── Order.java
│ ├── client
│ ├── LinkLamda_test.java
│ ├── QuickStartV2_test.java
│ ├── QuickStart_test.java
│ ├── constants
│ │ ├── OrderEvent.java
│ │ └── OrderState.java
│ └── v2
│ │ ├── OrderStateMachineImplV2.java
│ │ └── OrderStateMachineV2.java
│ ├── core
│ ├── Converter_Test.java
│ ├── DependProvider_test.java
│ ├── MvelScriptManager_test.java
│ ├── ReflectUtil_test.java
│ ├── Swith.java
│ └── support
│ │ └── SwithImpl.java
│ └── filter
│ ├── MvelChecker_test.java
│ └── PostProcessor_test.java
└── resources
└── spring-statemachine.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
49 |
50 |
51 | #my
52 | /target/
53 | /.classpath
54 | /.settings
55 | /.project
56 | /.idea
57 | *.iml
58 | /.springBeans
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.github.middleware
7 | j-statemachine
8 | 1.5.1.RELEASE
9 |
10 | jar
11 |
12 | 3.2.12.RELEASE
13 |
14 |
15 |
16 |
17 | com.google.guava
18 | guava
19 | 19.0
20 |
21 |
22 | org.apache.commons
23 | commons-lang3
24 | 3.4
25 |
26 |
27 | org.mvel
28 | mvel2
29 | 2.2.4.Final
30 |
31 |
32 |
33 | org.slf4j
34 | slf4j-api
35 | 1.7.21
36 |
37 |
38 | ch.qos.logback
39 | logback-core
40 | 1.1.3
41 |
42 |
43 | ch.qos.logback
44 | logback-classic
45 | 1.1.3
46 |
47 |
48 | com.alibaba
49 | fastjson
50 | 1.1.41
51 |
52 |
53 |
54 | org.springframework
55 | spring-core
56 | ${spring.version}
57 |
58 |
59 | org.springframework
60 | spring-beans
61 | ${spring.version}
62 |
63 |
64 | org.springframework
65 | spring-context
66 | ${spring.version}
67 |
68 |
69 | org.springframework
70 | spring-test
71 | ${spring.version}
72 |
73 |
74 |
75 | junit
76 | junit
77 | 4.12
78 | test
79 |
80 |
81 | org.hamcrest
82 | hamcrest-all
83 | 1.3
84 | test
85 |
86 |
87 |
88 |
89 | snapshots
90 | http://192.168.1.180:8091/nexus/content/repositories/snapshots
91 |
92 |
93 | releases
94 | http://192.168.1.180:8091/nexus/content/repositories/releases
95 |
96 |
97 |
98 |
99 |
100 | maven-compiler-plugin
101 |
102 | 1.8
103 | 1.8
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/StateMachine.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder;
2 |
3 | import com.github.middleware.fsm.builder.event.*;
4 | import com.github.middleware.fsm.builder.state.StateDefine;
5 | import com.github.middleware.fsm.config.application.StateMachineConfig;
6 | import com.github.middleware.fsm.exception.StateMachineException;
7 |
8 | import java.util.Set;
9 |
10 | /**
11 | * 有限状态机定义
12 | *
13 | * @param 状态机
14 | * @param 状态源:String/Enum
15 | * @param 触发事件:String/Enum
16 | * @param 携带报文
17 | */
18 | public interface StateMachine, S, E, C> {
19 | /**
20 | * 触发事件
21 | *
22 | * @param event
23 | */
24 | void handleEvent(E event);
25 |
26 | void handleEvent(E event, C context);
27 | void handleEvent(S initialStateName,E event, C context);
28 | /**
29 | * 测试状态扭转,并返回结果
30 | *
31 | * @param event
32 | * @param context
33 | * @return
34 | */
35 | //S test(E event, C context);
36 |
37 | /**
38 | * 测试事件是否有效
39 | *
40 | * @param event
41 | * @return
42 | */
43 | boolean canAccept(E event);
44 |
45 | /**
46 | * 状态机标示
47 | *
48 | * @return
49 | */
50 | String identifier();
51 |
52 | void identifier(String id);
53 |
54 | /**
55 | * 状态机的实例
56 | *
57 | * @return
58 | */
59 | StateMachine getThis();
60 |
61 | /**
62 | * 获取所有状态
63 | *
64 | * @return
65 | */
66 | Set getStates();
67 |
68 | /**
69 | * 获取初始化状态
70 | *
71 | * @return
72 | */
73 | S getInitialState();
74 |
75 | StateDefine getInitialRawState();
76 |
77 | /**
78 | * 获取当前状态
79 | *
80 | * @return
81 | */
82 | S getCurrentState();
83 |
84 | StateDefine getCurrentRawState();
85 |
86 | /**
87 | * 获取最终状态
88 | *
89 | * @return
90 | */
91 | S getLastState();
92 |
93 | StateDefine getLastRawState();
94 |
95 | /**
96 | * 获取执行异常信息
97 | *
98 | * @return
99 | */
100 | StateMachineException getLastException();
101 |
102 | StateMachineConfig getConfig();
103 | /**
104 | * transition action
105 | *
106 | * @param fromState
107 | * @param toState
108 | * @param event
109 | * @param context
110 | */
111 | void beforeActionInvoked(S fromState, S toState, E event, C context);
112 |
113 | void afterActionInvoked(S fromState, S toState, E event, C context);
114 |
115 | /**
116 | * 添加各种listener
117 | *
118 | * @param listener
119 | */
120 | void addTransitionBeginListener(TransitionBeginListener listener);
121 |
122 | void removeTransitionBeginListener(TransitionBeginListener listener);
123 |
124 | void addTransitionCompleteListener(TransitionCompleteListener listener);
125 |
126 | void removeTransitionCompleteListener(TransitionCompleteListener listener);
127 |
128 | void addTransitionExceptionListener(TransitionExceptionListener listener);
129 |
130 | void removeTransitionExceptionListener(TransitionExceptionListener listener);
131 |
132 | void addTransitionDeclinedListener(TransitionDeclinedListener listener);
133 |
134 | void removeTransitionDeclinedListener(TransitionDeclinedListener listener);
135 |
136 | void addTransitionEndListener(TransitionEndListener listener);
137 |
138 | void removeTransitionEndListener(TransitionEndListener listener);
139 |
140 | void addExecActionListener(BeforeExecActionListener listener);
141 |
142 | void removeExecActionListener(BeforeExecActionListener listener);
143 |
144 | /**
145 | * 启动各种插件支持
146 | */
147 | void pluginsStart();
148 | /**
149 | * 触发事件执行流
150 | *
151 | * @param fromStateId
152 | * @param event
153 | * @param context
154 | */
155 | // void beforeTransitionBegin(S fromStateId, E event, C context);
156 | // void afterTransitionDeclined(S fromStateId, E event, C context);
157 | // void afterTransitionCompleted(S fromStateId, Object currentState, E event, C context);
158 | // void afterTransitionCausedException(S fromStateId, S toStateId, E event, C context);
159 | // void afterTransitionEnd(S fromStateId, Object currentState, E event, C context);
160 | }
161 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/From.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.el.Dsl;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/6
10 | */
11 | public interface From, S, E, C> extends Dsl {
12 | To to(S state);
13 |
14 | To toEnd(S state);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/LocalTransitionBuilder.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/7
9 | */
10 | public interface LocalTransitionBuilder, S, E, C> {
11 | From from(S state);
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/On.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.filter.validator.PreChecker;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/6
10 | */
11 | public interface On, S, E, C> extends When {
12 | When when(PreChecker checker);
13 | When whenMvel(String expression);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/To.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.el.Dsl;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/6
10 | */
11 | public interface To, S, E, C> extends Dsl {
12 | On on(E event);
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/TransitionActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.state.StateDefine;
4 | import com.github.middleware.fsm.builder.state.dto.StateContext;
5 | import com.github.middleware.fsm.builder.StateMachine;
6 |
7 | /**
8 | * 扭转交互
9 | * Created by YT on 2017/3/8.
10 | */
11 | public interface TransitionActivity, S, E, C> {
12 | /**
13 | * 触发扭转链检查
14 | *
15 | * @param stateContext
16 | */
17 | void fireInternal(StateContext stateContext);
18 |
19 | /**
20 | * 执行 transition action
21 | *
22 | * @param stateContext
23 | * @return
24 | */
25 | StateDefine pass(StateContext stateContext);
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/TransitionCriteria.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.el.Dsl;
5 | import com.github.middleware.fsm.builder.exec.Action;
6 | import com.github.middleware.fsm.filter.validator.PreChecker;
7 |
8 | /**
9 | * 链式语法支持
10 | *
11 | * @author alex.chen
12 | * @version 1.0.0
13 | * @date 2017/2/28
14 | */
15 | @Deprecated
16 | public interface TransitionCriteria, S, E, C> extends Dsl {
17 | @Deprecated
18 | TransitionDefine to(S stateName);
19 | @Deprecated
20 | TransitionDefine toChoice(S choiceName);
21 | @Deprecated
22 | TransitionDefine onEvent(E event);
23 | @Deprecated
24 | TransitionDefine preCheckerElse();
25 | @Deprecated
26 | TransitionDefine preChecker(PreChecker preChecker);
27 | @Deprecated
28 | TransitionDefine withAction(Action action);
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/TransitionDefine.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.state.StateDefine;
4 | import com.github.middleware.fsm.builder.StateMachine;
5 | import com.github.middleware.fsm.filter.validator.PreChecker;
6 | import com.github.middleware.fsm.builder.exec.Action;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * 状态扭转链
12 | *
13 | * @author alex.chen
14 | * @version 1.0.0
15 | * @date 2017/2/27
16 | */
17 | public interface TransitionDefine, S, E, C> extends TransitionActivity, TransitionCriteria {
18 | void setFromState(StateDefine state);
19 | void setToState(StateDefine state);
20 | void setPreChecker(PreChecker preChecker);
21 | void addAction(Action action);
22 | void setEvent(E event);
23 |
24 | E getEvent();
25 | StateDefine getFromState();
26 | StateDefine getToState();
27 | PreChecker getPreChecker();
28 | List getActionList();
29 | boolean isEqual(S fromState, S toState, E event);
30 | boolean isEqual(S fromState, S toState, E event, Class> checker);
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/When.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 | import com.github.middleware.fsm.core.el.Dsl;
6 |
7 | /**
8 | * @author alex.chen
9 | * @version 1.0.0
10 | * @date 2017/3/6
11 | */
12 | public interface When, S, E, C> extends Dsl {
13 | /**
14 | * 完成
15 | *
16 | * @param action
17 | */
18 | void complete(Action action);
19 | void complete(String callMethod);
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/dto/TransitionResult.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain.dto;
2 |
3 | import com.github.middleware.fsm.builder.state.StateDefine;
4 | import com.google.common.collect.Lists;
5 | import com.github.middleware.fsm.builder.StateMachine;
6 |
7 | import java.io.Serializable;
8 | import java.util.Collections;
9 | import java.util.List;
10 |
11 | /**
12 | * @author alex.chen
13 | * @version 1.0.0
14 | * @date 2017/3/8
15 | */
16 | public class TransitionResult, S, E, C> implements Serializable {
17 | private boolean accepted;
18 | private StateDefine toState;
19 | private TransitionResult parent;
20 | private List> subResults;
21 |
22 | public TransitionResult(boolean accepted, StateDefine toState, TransitionResult parent) {
23 | this.accepted = accepted;
24 | this.toState = toState;
25 | this.parent = parent;
26 | }
27 |
28 | private void addSubResult(TransitionResult subResult) {
29 | if (subResults == null)
30 | subResults = Lists.newArrayList();
31 | subResults.add(subResult);
32 | }
33 |
34 | public boolean isAccepted() {
35 | if (accepted) {
36 | return true;
37 | } else if (subResults != null) {
38 | for (TransitionResult subResult : getSubResults()) {
39 | if (subResult.isAccepted()) return true;
40 | }
41 | }
42 | return false;
43 | }
44 |
45 | public TransitionResult setAccepted(boolean accepted) {
46 | this.accepted = accepted;
47 | return this;
48 | }
49 |
50 | public StateDefine getToState() {
51 | return toState;
52 | }
53 |
54 | public TransitionResult setToState(StateDefine toState) {
55 | this.toState = toState;
56 | return this;
57 | }
58 |
59 | public List> getSubResults() {
60 | return subResults != null ? Lists.newArrayList(subResults) :
61 | Collections.>emptyList();
62 | }
63 |
64 | public TransitionResult setParent(TransitionResult parent) {
65 | this.parent = parent;
66 | if (parent != null && parent instanceof TransitionResult) {
67 | ((TransitionResult) parent).addSubResult(this);
68 | }
69 | return this;
70 | }
71 |
72 | public TransitionResult getParentResut() {
73 | return parent;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/chain/support/LocalTransitionBuilderImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.chain.support;
2 |
3 | import com.github.middleware.fsm.builder.chain.*;
4 | import com.github.middleware.fsm.builder.state.StateDefine;
5 | import com.github.middleware.fsm.builder.StateMachine;
6 | import com.github.middleware.fsm.builder.StateMachines;
7 | import com.github.middleware.fsm.builder.exec.Action;
8 | import com.github.middleware.fsm.builder.exec.dto.RuleExecContext;
9 | import com.github.middleware.fsm.builder.chain.TransitionDefine;
10 | import com.github.middleware.fsm.filter.validator.PreChecker;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.util.Map;
15 |
16 | /**
17 | * @author alex.chen
18 | * @version 1.0.0
19 | * @date 2017/3/7
20 | */
21 | public class LocalTransitionBuilderImpl, S, E, C> implements LocalTransitionBuilder, From, To, On {
22 | private static final Logger LOGGER = LoggerFactory.getLogger(LocalTransitionBuilderImpl.class);
23 | private Map> states;
24 | private RuleExecContext execContext;
25 | private StateDefine from;
26 | private StateDefine to;
27 | private TransitionDefine transition;
28 |
29 |
30 | public LocalTransitionBuilderImpl(Map> states, RuleExecContext execContext) {
31 | this.states = states;
32 | this.execContext = execContext;
33 | }
34 |
35 | @Override
36 | public From from(S state) {
37 | from = StateMachines.getState(states, state);
38 | return this;
39 | }
40 |
41 | @Override
42 | public To to(S stateId) {
43 | to = StateMachines.getState(states, stateId);
44 | return this;
45 | }
46 |
47 | @Override
48 | public To toEnd(S stateId) {
49 | to = StateMachines.getState(states, stateId);
50 | if (!to.isEndState()) {
51 | to.setEndState(true);
52 | }
53 | return this;
54 | }
55 |
56 | @Override
57 | public On on(E event) {
58 | transition = from.addTransitionOn(event);
59 | transition.setToState(to);
60 | LOGGER.debug("fsm.load add Transition On:" + from.getName() + ">" + to.getName() + ">" + event);
61 | return this;
62 | }
63 |
64 | @Override
65 | public When when(PreChecker checker) {
66 | transition.setPreChecker(checker);
67 | return this;
68 | }
69 |
70 | @Override
71 | public When whenMvel(String expression) {
72 | PreChecker checker = StateMachines.newMvelCondition(expression, execContext.getScriptManager());
73 | transition.setPreChecker(checker);
74 | return this;
75 | }
76 |
77 | @Override
78 | public void complete(Action action) {
79 | LOGGER.debug("fsm.load add Action:" + action.getName());
80 | transition.addAction(action);
81 | }
82 |
83 | @Override
84 | public void complete(String callMethod) {
85 | Action action = StateMachines.newMethodCallActionProxy(callMethod, execContext);
86 | transition.addAction(action);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/ActionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 |
6 | /**
7 | * action事件
8 | *
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface ActionEvent, S, E, C> extends BaseEvent {
14 | Action getExecutionTarget();
15 |
16 | S getFrom();
17 |
18 | S getTo();
19 |
20 | E getEvent();
21 |
22 | C getContext();
23 |
24 | T getStateMachine();
25 |
26 | int[] getMOfN();
27 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/AfterExecActionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface AfterExecActionEvent, S, E, C> extends ActionEvent {
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/AfterExecActionListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface AfterExecActionListener, S, E, C> extends BaseListener {
14 | String METHOD_NAME = "afterExecute";
15 | Method METHOD = ReflectUtil.getMethod(AfterExecActionListener.class, METHOD_NAME, new Class>[]{AfterExecActionEvent.class});
16 |
17 | void afterExecute(AfterExecActionEvent event);
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/AsyncEventListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | /**
4 | * 事件(开启异步多线程)
5 | *
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface AsyncEventListener {
11 | long timeout();
12 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/BaseEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | /**
4 | * 总事件
5 | *
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/6
9 | */
10 | public interface BaseEvent {
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/BaseListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | /**
4 | * Created by YT on 2017/3/16.
5 | */
6 | public interface BaseListener {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/BeforeExecActionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface BeforeExecActionEvent, S, E, C> extends ActionEvent {
11 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/BeforeExecActionListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface BeforeExecActionListener, S, E, C> extends BaseListener{
14 | public static final String METHOD_NAME = "beforeExecute";
15 | public static final Method METHOD = ReflectUtil.getMethod(
16 | BeforeExecActionListener.class, METHOD_NAME, new Class>[]{BeforeExecActionEvent.class});
17 |
18 | void beforeExecute(BeforeExecActionEvent event);
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/EventType.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 |
4 | /**
5 | * 好像只有全局事件,先废弃吧
6 | *
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/6
10 | */
11 | public enum EventType {
12 | Transition,
13 | Action
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/ExecActionExceptionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.exception.StateMachineException;
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface ExecActionExceptionEvent, S, E, C> extends ActionEvent {
11 | StateMachineException getException();
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/ExecActionExceptionListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface ExecActionExceptionListener, S, E, C> extends BaseListener {
14 | String METHOD_NAME = "executeException";
15 | Method METHOD = ReflectUtil.getMethod(ExecActionExceptionListener.class, METHOD_NAME, new Class>[]{ExecActionExceptionEvent.class});
16 |
17 | void executeException(ExecActionExceptionEvent event);
18 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/ListenerMapping.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.event.annotation.*;
4 |
5 | /**
6 | * Created by YT on 2017/3/16.
7 | */
8 | public interface ListenerMapping {
9 | String LISTENER_ANNOTATION_WHEN_NAME = "when";
10 | String LISTENER_FIELD_NAME="METHOD";
11 | Class>[][] SATE_LISTENER_MAPPING = {
12 | {OnTransitionBegin.class, TransitionBeginListener.class, TransitionBeginEvent.class},
13 | {OnTransitionComplete.class, TransitionCompleteListener.class, TransitionCompleteEvent.class},
14 | {OnTransitionDecline.class, TransitionDeclinedListener.class, TransitionDeclinedEvent.class},
15 | {OnTransitionEnd.class, TransitionEndListener.class, TransitionEndEvent.class},
16 | {OnTransitionException.class, TransitionExceptionListener.class, TransitionExceptionEvent.class}
17 | };
18 | Class>[][] ACTION_LISTENR_MAPPING = {
19 | {OnBeforeAction.class, BeforeExecActionListener.class, BeforeExecActionEvent.class},
20 | {OnAfterAction.class, AfterExecActionListener.class, AfterExecActionEvent.class},
21 | {OnActionException.class, ExecActionExceptionListener.class, ExecActionExceptionEvent.class},
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/StateMachineEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * 状态机事件:
7 | * TODO:赞未使用
8 | *
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface StateMachineEvent, S, E, C> extends BaseEvent {
14 | T getStateMachine();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionBeginEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface TransitionBeginEvent, S, E, C> extends TransitionEvent {
11 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionBeginListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface TransitionBeginListener, S, E, C> extends BaseListener {
14 | String METHOD_NAME = "transitionBegin";
15 | Method METHOD = ReflectUtil.getMethod(TransitionBeginListener.class, METHOD_NAME, new Class>[]{TransitionBeginEvent.class});
16 |
17 | void transitionBegin(TransitionBeginEvent event);
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionCompleteEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface TransitionCompleteEvent, S, E, C> extends TransitionEvent {
11 | S getTargetState();
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionCompleteListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface TransitionCompleteListener, S, E, C> extends BaseListener{
14 | String METHOD_NAME = "transitionComplete";
15 | Method METHOD = ReflectUtil.getMethod(TransitionCompleteListener.class, METHOD_NAME, new Class>[]{TransitionCompleteEvent.class});
16 |
17 | void transitionComplete(TransitionCompleteEvent event);
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionDeclinedEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface TransitionDeclinedEvent, S, E, C> extends TransitionEvent {
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionDeclinedListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface TransitionDeclinedListener, S, E, C> extends BaseListener {
14 | String METHOD_NAME = "transitionDeclined";
15 | Method METHOD = ReflectUtil.getMethod(TransitionDeclinedListener.class, METHOD_NAME, new Class>[]{TransitionDeclinedEvent.class});
16 |
17 | void transitionDeclined(TransitionDeclinedEvent event);
18 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionEndEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | public interface TransitionEndEvent, S, E, C> extends TransitionEvent {
11 | S getTargetState();
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionEndListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface TransitionEndListener, S, E, C> extends BaseListener{
14 | String METHOD_NAME = "transitionEnd";
15 | Method METHOD = ReflectUtil.getMethod(TransitionEndListener.class, METHOD_NAME, new Class>[]{TransitionEndEvent.class});
16 |
17 | void transitionEnd(TransitionEndEvent event);
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * 扭转事件
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public interface TransitionEvent, S, E, C> extends StateMachineEvent {
12 | S getSourceState();
13 |
14 | E getCause();
15 |
16 | C getContext();
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionExceptionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.exception.StateMachineException;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public interface TransitionExceptionEvent, S, E, C> extends TransitionEvent {
12 | S getTargetState();
13 |
14 | StateMachineException getException();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/TransitionExceptionListener.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.core.utils.ReflectUtil;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/8
12 | */
13 | public interface TransitionExceptionListener, S, E, C> extends BaseListener{
14 | String METHOD_NAME = "transitionException";
15 | Method METHOD = ReflectUtil.getMethod(TransitionExceptionListener.class, METHOD_NAME, new Class>[]{TransitionExceptionEvent.class});
16 |
17 | void transitionException(TransitionExceptionEvent event);
18 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/AsyncExec.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/17
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target({ElementType.TYPE, ElementType.METHOD})
13 | public @interface AsyncExec {
14 | long timeout() default -1;
15 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/ListenerOrder.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Deprecated
11 | @Documented
12 | @Retention(RetentionPolicy.RUNTIME)
13 | @Target({ElementType.TYPE, ElementType.METHOD})
14 | public @interface ListenerOrder {
15 | int value();
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnActionException.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnActionException {
14 | String when() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnAfterAction.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnAfterAction {
14 | String when() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnBeforeAction.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnBeforeAction {
14 | String when() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnTransitionBegin.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnTransitionBegin {
14 | String when() default "";
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnTransitionComplete.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnTransitionComplete {
14 | String when() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnTransitionDecline.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnTransitionDecline {
14 | String when() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnTransitionEnd.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnTransitionEnd {
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/annotation/OnTransitionException.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/8
9 | */
10 | @Documented
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.METHOD)
13 | public @interface OnTransitionException {
14 | String when() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/dto/ListenerMappingContext.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.dto;
2 |
3 | import com.github.middleware.fsm.builder.plugin.PluginProvider;
4 | import com.google.common.collect.Lists;
5 |
6 | import java.io.Serializable;
7 | import java.util.List;
8 |
9 | /**
10 | * @author alex.chen
11 | * @version 1.0.0
12 | * @date 2017/3/16
13 | */
14 | public class ListenerMappingContext implements Serializable {
15 | private PluginProvider pluginProvider;
16 | private List mappingContextItems;
17 |
18 | public ListenerMappingContext() {
19 | this(null);
20 | }
21 |
22 | public ListenerMappingContext(PluginProvider pluginProvider) {
23 | this.pluginProvider = pluginProvider;
24 | mappingContextItems = Lists.newArrayList();
25 | }
26 |
27 | public PluginProvider getPluginProvider() {
28 | return pluginProvider;
29 | }
30 |
31 | public void setPluginProvider(PluginProvider pluginProvider) {
32 | this.pluginProvider = pluginProvider;
33 | }
34 |
35 | public List getMappingContextItems() {
36 | return mappingContextItems;
37 | }
38 |
39 | public void addMappingContextItem(ListenerMappingContextItem mappingContextItem) {
40 | if (mappingContextItem != null) this.mappingContextItems.add(mappingContextItem);
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return "ListenerMappingContext{" +
46 | "pluginProvider=" + pluginProvider +
47 | ", mappingContextItems=" + mappingContextItems +
48 | '}';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/dto/ListenerMappingContextItem.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.dto;
2 |
3 | import com.github.middleware.fsm.builder.event.BaseEvent;
4 | import com.github.middleware.fsm.builder.event.BaseListener;
5 | import com.github.middleware.fsm.builder.event.EventType;
6 |
7 | import java.io.Serializable;
8 | import java.lang.annotation.Annotation;
9 | import java.lang.reflect.Method;
10 |
11 | /**
12 | * @author alex.chen
13 | * @version 1.0.0
14 | * @date 2017/3/20
15 | */
16 | public class ListenerMappingContextItem implements Serializable {
17 | private EventType eventType;
18 | private Class extends Annotation> listenerAn;
19 | private Class extends BaseListener> listenerClz;
20 | private Class extends BaseEvent> listenerEvent;
21 | //监听状态机事件的函数
22 | private Method listenrMethod;
23 | private Object proxylistenerMethod;
24 | //触发执行函数
25 | private Method firePluginMethod;
26 | private String when;
27 |
28 | public ListenerMappingContextItem(Class extends Annotation> listenerAn, Class extends BaseListener> listenerClz, Class extends BaseEvent> listenerEvent) {
29 | this.listenerAn = listenerAn;
30 | this.listenerEvent = listenerEvent;
31 | this.listenerClz = listenerClz;
32 | }
33 |
34 | public Class extends Annotation> getListenerAn() {
35 | return listenerAn;
36 | }
37 |
38 | public void setListenerAn(Class extends Annotation> listenerAn) {
39 | this.listenerAn = listenerAn;
40 | }
41 |
42 | public Class extends BaseListener> getListenerClz() {
43 | return listenerClz;
44 | }
45 |
46 | public void setListenerClz(Class extends BaseListener> listenerClz) {
47 | this.listenerClz = listenerClz;
48 | }
49 |
50 | public Class extends BaseEvent> getListenerEvent() {
51 | return listenerEvent;
52 | }
53 |
54 | public void setListenerEvent(Class extends BaseEvent> listenerEvent) {
55 | this.listenerEvent = listenerEvent;
56 | }
57 |
58 | public Method getListenrMethod() {
59 | return listenrMethod;
60 | }
61 |
62 | public void setListenrMethod(Method listenrMethod) {
63 | this.listenrMethod = listenrMethod;
64 | }
65 |
66 | public Object getProxylistenerMethod() {
67 | return proxylistenerMethod;
68 | }
69 |
70 | public void setProxylistenerMethod(Object proxylistenerMethod) {
71 | this.proxylistenerMethod = proxylistenerMethod;
72 | }
73 |
74 | public Method getFirePluginMethod() {
75 | return firePluginMethod;
76 | }
77 |
78 | public void setFirePluginMethod(Method firePluginMethod) {
79 | this.firePluginMethod = firePluginMethod;
80 | }
81 |
82 | public String getWhen() {
83 | return when;
84 | }
85 |
86 | public void setWhen(String when) {
87 | this.when = when;
88 | }
89 |
90 | public EventType getEventType() {
91 | return eventType;
92 | }
93 |
94 | public void setEventType(EventType eventType) {
95 | this.eventType = eventType;
96 | }
97 |
98 | @Override
99 | public String toString() {
100 | return "ListenerMappingContextItem{" +
101 | "eventType=" + eventType +
102 | ", listenerAn=" + listenerAn +
103 | ", listenerClz=" + listenerClz +
104 | ", listenerEvent=" + listenerEvent +
105 | ", listenrMethod=" + listenrMethod +
106 | ", proxylistenerMethod=" + proxylistenerMethod +
107 | ", firePluginMethod=" + firePluginMethod +
108 | ", when='" + when + '\'' +
109 | '}';
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/dto/ListenerMethod.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.dto;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.github.middleware.fsm.builder.event.AsyncEventListener;
5 | import com.github.middleware.fsm.core.factory.ThreadExecutorService;
6 | import com.github.middleware.fsm.core.utils.Precondition;
7 | import com.github.middleware.fsm.core.utils.ReflectUtil;
8 | import com.github.middleware.fsm.exception.StateMachineException;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.io.Serializable;
13 | import java.lang.reflect.Method;
14 |
15 | /**
16 | * @author alex.chen
17 | * @version 1.0.0
18 | * @date 2017/3/8
19 | */
20 | public class ListenerMethod implements Serializable {
21 | private static final Logger LOGGER = LoggerFactory.getLogger(ListenerMethod.class);
22 | private Class> eventType;
23 | private Object target;
24 | private Method method;
25 | private boolean hasParameter = false;
26 | private boolean isAsync;
27 | private long timeout;
28 |
29 | public ListenerMethod(Class> eventType, Object listener, Method method) {
30 | Preconditions.checkArgument(eventType != null && listener != null && method != null, "校验异常:入参不能为空!");
31 | Preconditions.checkArgument(method.getDeclaringClass().isAssignableFrom(listener.getClass()), "校验异常:" + method.getName() + "不适用于 " + listener.getClass().getName());
32 | this.eventType = eventType;
33 | this.target = listener;
34 | this.method = method;
35 | this.isAsync = AsyncEventListener.class.isAssignableFrom(listener.getClass());
36 | this.timeout = isAsync ? AsyncEventListener.class.cast(listener).timeout() : -1;
37 | final Class>[] params = method.getParameterTypes();
38 | if (params.length > 0) {
39 | if (params.length == 1 && params[0].isAssignableFrom(eventType)) {
40 | hasParameter = true;
41 | } else {
42 | throw new StateMachineException("校验异常:参数类型异常!");
43 | }
44 | }
45 | }
46 |
47 | public void invokeMethod(final Object event) {
48 | // LOGGER.info("fsm.fire global event," + JSON.toJSONString(this));
49 | LOGGER.info("fsm.fire global event," + event);
50 | Precondition.checkState(eventType.isAssignableFrom(event.getClass()), "校验异常:类型不匹配.");
51 | if (isAsync) {
52 | ThreadExecutorService.getExecutor().execute(() -> ReflectUtil.invoke(method, target, hasParameter ? new Object[]{event} : new Object[0]));
53 | } else {
54 | synchronized (target) {
55 | ReflectUtil.invoke(method, target, hasParameter ? new Object[]{event} : new Object[0]);
56 | }
57 | }
58 | }
59 |
60 | public Class> getEventType() {
61 | return eventType;
62 | }
63 |
64 | public boolean matches(Class> eventType, Object target) {
65 | return (this.target == target) && (eventType.equals(this.eventType));
66 | }
67 |
68 | public boolean matches(Class> eventType, Object target, Method method) {
69 | return (this.target == target) && (eventType.equals(this.eventType) && method.equals(this.method));
70 | }
71 |
72 | @Override
73 | public boolean equals(Object obj) {
74 | if (this == obj) {
75 | return true;
76 | }
77 | if ((obj == null) || (obj.getClass() != getClass())) {
78 | return false;
79 | }
80 | ListenerMethod t = (ListenerMethod) obj;
81 | return (eventType == t.eventType || (eventType != null && eventType.equals(t.eventType)))
82 | && (target == t.target || (target != null && target.equals(t.target)))
83 | && (method == t.method || (method != null && method.equals(t.method)));
84 | }
85 |
86 | @Override
87 | public String toString() {
88 | return new StringBuilder(target.getClass().getSimpleName()).
89 | append('.').append(method.getName()).append('(').
90 | append(eventType.getSimpleName()).append(')').toString();
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/AbstractExecActionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.ActionEvent;
5 | import com.github.middleware.fsm.builder.exec.Action;
6 | import com.github.middleware.fsm.builder.exec.dto.ExecServiceContext;
7 | import com.github.middleware.fsm.builder.exec.support.ActionImpl;
8 |
9 | /**
10 | * @author alex.chen
11 | * @version 1.0.0
12 | * @date 2017/3/14
13 | */
14 | public abstract class AbstractExecActionEvent, S, E, C> implements ActionEvent {
15 | private ExecServiceContext execServiceContext;
16 | private int pos;
17 | private int size;
18 |
19 | public AbstractExecActionEvent(ExecServiceContext execServiceContext) {
20 | this.execServiceContext = execServiceContext;
21 | }
22 |
23 | public AbstractExecActionEvent(int pos, int size, ExecServiceContext execServiceContext) {
24 | this.pos = pos;
25 | this.size = size;
26 | this.execServiceContext = execServiceContext;
27 | }
28 |
29 | @Override
30 | public Action getExecutionTarget() {
31 | // user can only read action info but cannot invoke action in the listener method
32 | return new ActionImpl(execServiceContext.getAction());
33 | }
34 |
35 | @Override
36 | public S getFrom() {
37 | return execServiceContext.getFrom();
38 | }
39 |
40 | @Override
41 | public S getTo() {
42 | return execServiceContext.getTo();
43 | }
44 |
45 | @Override
46 | public E getEvent() {
47 | return execServiceContext.getEvent();
48 | }
49 |
50 | @Override
51 | public C getContext() {
52 | return execServiceContext.getContext();
53 | }
54 |
55 | @Override
56 | public T getStateMachine() {
57 | return execServiceContext.getStateMachine();
58 | }
59 |
60 | @Override
61 | public int[] getMOfN() {
62 | return new int[]{pos, size};
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/AbstractStateMachineEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.StateMachineEvent;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public abstract class AbstractStateMachineEvent, S, E, C> implements StateMachineEvent {
12 | private T stateMachine;
13 |
14 | public AbstractStateMachineEvent(T stateMachine) {
15 | this.stateMachine = stateMachine;
16 | }
17 | @Override
18 | public T getStateMachine() {
19 | return stateMachine;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/AbstractTransitionEvent.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.TransitionEvent;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public abstract class AbstractTransitionEvent, S, E, C> extends AbstractStateMachineEvent implements TransitionEvent {
12 | private S sourceState;
13 | private E event;
14 | private C context;
15 |
16 | public AbstractTransitionEvent(S sourceState, E event, C context, T stateMachine) {
17 | super(stateMachine);
18 | this.sourceState = sourceState;
19 | this.event = event;
20 | this.context = context;
21 | }
22 |
23 | @Override
24 | public S getSourceState() {
25 | return sourceState;
26 | }
27 |
28 | @Override
29 | public E getCause() {
30 | return event;
31 | }
32 |
33 | @Override
34 | public C getContext() {
35 | return context;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/AfterExecActionEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.event.AfterExecActionEvent;
4 | import com.github.middleware.fsm.builder.StateMachine;
5 | import com.github.middleware.fsm.builder.exec.dto.ExecServiceContext;
6 |
7 | /**
8 | * @author alex.chen
9 | * @version 1.0.0
10 | * @date 2017/3/20
11 | */
12 | public class AfterExecActionEventImpl, S, E, C> extends AbstractExecActionEvent implements AfterExecActionEvent {
13 | public AfterExecActionEventImpl(ExecServiceContext execServiceContext) {
14 | super(execServiceContext);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/BeforeExecActionEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.event.BeforeExecActionEvent;
4 | import com.github.middleware.fsm.builder.StateMachine;
5 | import com.github.middleware.fsm.builder.exec.dto.ExecServiceContext;
6 |
7 | /**
8 | * @author alex.chen
9 | * @version 1.0.0
10 | * @date 2017/3/14
11 | */
12 | public class BeforeExecActionEventImpl, S, E, C> extends AbstractExecActionEvent implements BeforeExecActionEvent {
13 |
14 | public BeforeExecActionEventImpl(ExecServiceContext actionContext) {
15 | super(actionContext);
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/ExecActionExceptionEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.ExecActionExceptionEvent;
5 | import com.github.middleware.fsm.builder.exec.dto.ExecServiceContext;
6 | import com.github.middleware.fsm.exception.StateMachineException;
7 |
8 | /**
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/20
12 | */
13 | public class ExecActionExceptionEventImpl, S, E, C> extends AbstractExecActionEvent implements ExecActionExceptionEvent {
14 | private StateMachineException e;
15 |
16 | public ExecActionExceptionEventImpl(ExecServiceContext execServiceContext, StateMachineException error) {
17 | super(execServiceContext);
18 | this.e = error;
19 | }
20 |
21 | @Override
22 | public StateMachineException getException() {
23 | return e;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/TransitionBeginEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.event.TransitionBeginEvent;
4 | import com.github.middleware.fsm.builder.StateMachine;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public class TransitionBeginEventImpl, S, E, C> extends AbstractTransitionEvent implements TransitionBeginEvent {
12 | public TransitionBeginEventImpl(S sourceState, E event, C context, T stateMachine) {
13 | super(sourceState, event, context, stateMachine);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/TransitionCompleteEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.TransitionCompleteEvent;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public class TransitionCompleteEventImpl, S, E, C> extends AbstractTransitionEvent implements TransitionCompleteEvent {
12 | private S targetState;
13 |
14 | public TransitionCompleteEventImpl(S sourceState, S targetState, E event, C context, T stateMachine) {
15 | super(sourceState, event, context, stateMachine);
16 | this.targetState = targetState;
17 | }
18 |
19 | @Override
20 | public S getTargetState() {
21 | return targetState;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/TransitionDeclinedEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.TransitionDeclinedEvent;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public class TransitionDeclinedEventImpl, S, E, C> extends AbstractTransitionEvent implements TransitionDeclinedEvent {
12 | public TransitionDeclinedEventImpl(S sourceState, E event, C context, T stateMachine) {
13 | super(sourceState, event, context, stateMachine);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/TransitionEndEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.TransitionEndEvent;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public class TransitionEndEventImpl, S, E, C> extends AbstractTransitionEvent implements TransitionEndEvent {
12 | private S targetState;
13 |
14 | public TransitionEndEventImpl(S sourceState, S targetState, E event, C context, T stateMachine) {
15 | super(sourceState, event, context, stateMachine);
16 | this.targetState = targetState;
17 | }
18 |
19 | @Override
20 | public S getTargetState() {
21 | return targetState;
22 | }
23 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/event/support/TransitionExceptionEventImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.event.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.TransitionExceptionEvent;
5 | import com.github.middleware.fsm.exception.StateMachineException;
6 |
7 | /**
8 | * @author alex.chen
9 | * @version 1.0.0
10 | * @date 2017/3/8
11 | */
12 | public class TransitionExceptionEventImpl, S, E, C> extends AbstractTransitionEvent implements TransitionExceptionEvent {
13 | private S targetState;
14 | private StateMachineException e;
15 |
16 | public TransitionExceptionEventImpl(StateMachineException e,
17 | S sourceState, S targetState, E event, C context, T stateMachine) {
18 | super(sourceState, event, context, stateMachine);
19 | this.targetState = targetState;
20 | this.e = e;
21 | }
22 |
23 | @Override
24 | public S getTargetState() {
25 | return targetState;
26 | }
27 |
28 | @Override
29 | public StateMachineException getException() {
30 | return e;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/Action.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.support.AbstractAction;
5 |
6 | /**
7 | * 执行动作,包含exit、entry、action
8 | *
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/2/27
12 | */
13 | public interface Action, S, E, C> {
14 | int WEIGHT_NORMAL = 0;
15 | int WEIGHT_BEFORE = 100;
16 | int WEIGHT_AFTER = -100;
17 | int WEIGHT_IGNORE = 1000;
18 |
19 | void execute(S from, S to, E event, C context, T stateMachine, String actionName);
20 |
21 | String getName();
22 |
23 | /**
24 | * 执行权重
25 | *
26 | * @return
27 | */
28 | @Deprecated
29 | int weight();
30 |
31 | /**
32 | * 异步
33 | *
34 | * @return
35 | */
36 | @Deprecated
37 | boolean isAsync();
38 |
39 | /**
40 | * 异步超时
41 | *
42 | * @return
43 | */
44 | @Deprecated
45 | long timeout();
46 |
47 |
48 | public final static Action DUMMY_ACTION = new AbstractAction() {
49 | @Override
50 | public void execute(Object from, Object to, Object event,
51 | Object context, StateMachine stateMachine, String serviceName) {
52 | // DO NOTHING
53 | }
54 |
55 | @Override
56 | public String getName() {
57 | return "__DUMMY_ACTION";
58 | }
59 | };
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/ActionExecService.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.event.BeforeExecActionListener;
5 | import com.github.middleware.fsm.builder.exec.dto.ExecServiceContext;
6 |
7 | import java.lang.reflect.Method;
8 |
9 | /**
10 | * @author alex.chen
11 | * @version 1.0.0
12 | * @date 2017/3/8
13 | */
14 | public interface ActionExecService, S, E, C> {
15 | void execute(ExecServiceContext execServiceContext);
16 |
17 | void addProxyListener(Class> eventType, Object listener, Method method);
18 |
19 | void addExecActionListener(BeforeExecActionListener listener);
20 |
21 | void removeExecActionListener(BeforeExecActionListener listener);
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/EntryExitBuilder.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.chain.When;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/7
10 | */
11 | public interface EntryExitBuilder, S, E, C> extends When {
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/annotation/ExecWhen.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/7
9 | */
10 | @Deprecated
11 | @Documented
12 | @Retention(RetentionPolicy.RUNTIME)
13 | @Target({ElementType.TYPE, ElementType.METHOD})
14 | public @interface ExecWhen {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/dto/ExecServiceContext.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.dto;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 | import com.github.middleware.fsm.builder.machine.support.AbstractStateMachine;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * @author alex.chen
11 | * @version 1.0.0
12 | * @date 2017/3/14
13 | */
14 | public class ExecServiceContext, S, E, C> implements Serializable {
15 | private String execServiceName;
16 | private Action action;
17 | private S from;
18 | S to;
19 | E event;
20 | C context;
21 | private T stateMachine;
22 |
23 | public ExecServiceContext() {
24 | }
25 |
26 | public S getFrom() {
27 | return from;
28 | }
29 |
30 | public S getTo() {
31 | return to;
32 | }
33 |
34 | public E getEvent() {
35 | return event;
36 | }
37 |
38 | public C getContext() {
39 | return context;
40 | }
41 |
42 | public T getStateMachine() {
43 | return stateMachine;
44 | }
45 |
46 | public Action getAction() {
47 | return action;
48 | }
49 |
50 | public ExecServiceContext setExecServiceName(String execServiceName) {
51 | this.execServiceName = execServiceName;
52 | return this;
53 | }
54 |
55 | public ExecServiceContext setAction(Action action) {
56 | this.action = action;
57 | return this;
58 | }
59 |
60 | public ExecServiceContext setFrom(S from) {
61 | this.from = from;
62 | return this;
63 | }
64 |
65 | public ExecServiceContext setTo(S to) {
66 | this.to = to;
67 | return this;
68 | }
69 |
70 | public ExecServiceContext setEvent(E event) {
71 | this.event = event;
72 | return this;
73 | }
74 |
75 | public ExecServiceContext setContext(C context) {
76 | this.context = context;
77 | return this;
78 | }
79 |
80 | public ExecServiceContext setStateMachine(T stateMachine) {
81 | this.stateMachine = stateMachine;
82 | return this;
83 | }
84 |
85 | /**
86 | * 执行
87 | * TODO:有的污染需改造
88 | */
89 | public void doAction() {
90 | AbstractStateMachine fsmImpl = (AbstractStateMachine) stateMachine;
91 | fsmImpl.beforeActionInvoked(from, to, event, context);
92 | action.execute(from, to, event, context, stateMachine,execServiceName);
93 |
94 | fsmImpl.afterActionInvoked(from, to, event, context);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/dto/RegularTransition.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.dto;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 |
6 | import java.io.Serializable;
7 | import java.util.List;
8 |
9 | /**
10 | * @author alex.chen
11 | * @version 1.0.0
12 | * @date 2017/3/7
13 | */
14 | public class RegularTransition, S, E, C> implements Serializable {
15 | private List extends Action> actions;
16 |
17 | private S from;
18 |
19 | private S to;
20 |
21 | private E event;
22 |
23 | public RegularTransition(S from, S to, E event) {
24 | this.from = from;
25 | this.to = to;
26 | this.event = event;
27 | }
28 |
29 | public S getFrom() {
30 | return from;
31 | }
32 |
33 | public S getTo() {
34 | return to;
35 | }
36 |
37 | public E getEvent() {
38 | return event;
39 | }
40 |
41 | public List extends Action> getActions() {
42 | return actions;
43 | }
44 |
45 | public void setActions(List extends Action> actions) {
46 | this.actions = actions;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/dto/RuleExecContext.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.dto;
2 |
3 | import com.github.middleware.fsm.core.el.MvelScriptManager;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | *
9 | * @author alex.chen
10 | * @version 1.0.0
11 | * @date 2017/3/7
12 | */
13 | public class RuleExecContext implements Serializable {
14 | private MvelScriptManager scriptManager;
15 | private Class> executionTargetType;
16 | private Class>[] methodCallParamTypes;
17 |
18 | public RuleExecContext(MvelScriptManager scriptManager, Class> executionTargetType, Class>[] methodCallParamTypes) {
19 | this.scriptManager = scriptManager;
20 | this.executionTargetType = executionTargetType;
21 | this.methodCallParamTypes = methodCallParamTypes;
22 | }
23 |
24 | public MvelScriptManager getScriptManager() {
25 | return scriptManager;
26 | }
27 |
28 | public Class> getExecutionTargetType() {
29 | return executionTargetType;
30 | }
31 |
32 | public Class>[] getMethodCallParamTypes() {
33 | return methodCallParamTypes;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/AbstractAction.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/7
10 | */
11 | public abstract class AbstractAction, S, E, C> implements Action {
12 |
13 | @Override
14 | public String getName() {
15 | return getClass().getSimpleName() + "_Action";
16 | }
17 |
18 | @Override
19 | public int weight() {
20 | return WEIGHT_NORMAL;
21 | }
22 |
23 | @Override
24 | final public String toString() {
25 | return "instance#" + getClass().getName();
26 | }
27 |
28 | @Override
29 | public boolean isAsync() {
30 | return false;
31 | }
32 |
33 | @Override
34 | public long timeout() {
35 | return -1;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/ActionExecServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.config.application.StateMachineConfig;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/8
10 | */
11 | public class ActionExecServiceImpl, S, E, C> extends AbstractExecService {
12 | public ActionExecServiceImpl(StateMachineConfig config) {
13 | super(config);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/ActionImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 | import com.github.middleware.fsm.exception.StateMachineException;
6 |
7 | /**
8 | * @author alex.chen
9 | * @version 1.0.0
10 | * @date 2017/3/14
11 | */
12 | public class ActionImpl, S, E, C> extends AbstractAction {
13 | private Action action;
14 |
15 | public ActionImpl(Action action) {
16 | this.action = action;
17 | }
18 |
19 | @Override
20 | public void execute(S from, S to, E event, C context, T stateMachine, String actionName) {
21 | throw new StateMachineException("未发生任何调用.");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/ActionWrapper.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.exec.Action;
5 |
6 | /**
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/7
10 | */
11 | public class ActionWrapper, S, E, C> implements Action {
12 | private Action delegator;
13 |
14 | public ActionWrapper(Action delegator) {
15 | this.delegator = delegator;
16 | }
17 |
18 | @Override
19 | public void execute(S from, S to, E event, C context, T stateMachine,String actionName) {
20 | delegator.execute(from, to, event, context, stateMachine,actionName);
21 | }
22 |
23 | @Override
24 | public String getName() {
25 | return delegator.getName();
26 | }
27 |
28 | @Override
29 | public int weight() {
30 | return delegator.weight();
31 | }
32 |
33 | @Override
34 | public long timeout() {
35 | return delegator.timeout();
36 | }
37 |
38 | @Override
39 | public boolean isAsync() {
40 | return false;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/EntryExitBuilderImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.github.middleware.fsm.builder.exec.dto.RuleExecContext;
4 | import com.github.middleware.fsm.builder.state.StateDefine;
5 | import com.github.middleware.fsm.builder.StateMachine;
6 | import com.github.middleware.fsm.builder.StateMachines;
7 | import com.github.middleware.fsm.builder.exec.Action;
8 | import com.github.middleware.fsm.builder.exec.EntryExitBuilder;
9 |
10 | /**
11 | * @author alex.chen
12 | * @version 1.0.0
13 | * @date 2017/3/7
14 | */
15 | public class EntryExitBuilderImpl, S, E, C> implements EntryExitBuilder {
16 | private boolean isEntryAction;
17 | private StateDefine state;
18 | private RuleExecContext execContext;
19 |
20 | public EntryExitBuilderImpl() {
21 |
22 | }
23 |
24 | public EntryExitBuilderImpl(StateDefine state, boolean isEntryAction, RuleExecContext execContext) {
25 | this.isEntryAction = isEntryAction;
26 | this.state = state;
27 | this.execContext = execContext;
28 | }
29 |
30 | @Override
31 | public void complete(Action action) {
32 | if (isEntryAction) {
33 | state.addEntryAction(action);
34 | } else {
35 | state.addExitAction(action);
36 | }
37 | }
38 | @Override
39 | public void complete(String callMethod) {
40 | Action action = StateMachines.newMethodCallActionProxy(callMethod, execContext);
41 | complete(action);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/MethodCallImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.alibaba.fastjson.annotation.JSONField;
4 | import com.github.middleware.fsm.builder.exec.dto.RuleExecContext;
5 | import com.google.common.base.Stopwatch;
6 | import com.google.common.base.Strings;
7 | import com.google.common.collect.Lists;
8 | import com.github.middleware.fsm.builder.StateMachine;
9 | import com.github.middleware.fsm.core.utils.ReflectUtil;
10 | import com.github.middleware.fsm.builder.exec.Action;
11 | import com.github.middleware.fsm.builder.plugin.log.LogExec;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.lang.reflect.Method;
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | /**
20 | * 方法调用
21 | *
22 | * @author alex.chen
23 | * @version 1.0.0
24 | * @date 2017/3/7
25 | */
26 | public class MethodCallImpl, S, E, C> implements Action {
27 | private static final Logger LOGGER = LoggerFactory.getLogger(MethodCallImpl.class);
28 | private Method method;
29 | private boolean logExec;
30 | private String scriptExpr;
31 | private int weight;
32 | @JSONField(serialize = false)
33 | private RuleExecContext execContext;
34 | private String serviceName;
35 |
36 | public MethodCallImpl(Method method, int weight, RuleExecContext execContext) {
37 | this.method = method;
38 | this.weight = Action.WEIGHT_NORMAL;
39 | this.execContext = execContext;
40 | if (method != null) {
41 | LogExec logExecObj = method.getAnnotation(LogExec.class);
42 | if (logExecObj != null) {
43 | if (!Strings.isNullOrEmpty(logExecObj.when())) {
44 | logExec = true;
45 | scriptExpr = logExecObj.when();
46 | this.execContext.getScriptManager().compile(scriptExpr);
47 | }
48 | }
49 | }
50 | }
51 |
52 | @Override
53 | public void execute(S from, S to, E event, C context, T stateMachine, String serviceName) {
54 | this.serviceName = serviceName;
55 | Object[] paramValues = Lists.newArrayList(from, to, event, context).subList(0, execContext.getMethodCallParamTypes().length).toArray();
56 | // LOGGER.info("fsm.fire exec start,method:" + methodToString(this.method) + ",scriptExpr:" + scriptExpr + ",paramValues:" + paramValues);
57 | if (scriptExpr != null) {
58 | Map variables = new HashMap();
59 | variables.put("context", context);
60 | boolean isAllowed = execContext.getScriptManager().evalBoolean(scriptExpr, variables);
61 | if (!isAllowed) return;
62 | }
63 | if (logExec) {
64 | Stopwatch sw = Stopwatch.createStarted();
65 | ReflectUtil.invoke(method, stateMachine, paramValues);
66 | LOGGER.info("fsm.fire exec," + getName() + " times:" + sw);
67 | } else {
68 | ReflectUtil.invoke(method, stateMachine, paramValues);
69 | }
70 | }
71 |
72 | @Override
73 | public String getName() {
74 | return serviceName + "." + method;
75 | }
76 |
77 | @Override
78 | public int weight() {
79 | return 0;
80 | }
81 |
82 | @Override
83 | public long timeout() {
84 | return 0;
85 | }
86 |
87 | @Override
88 | public boolean isAsync() {
89 | return false;
90 | }
91 |
92 | private String methodToString(Method method) {
93 | if (method == null)
94 | return null;
95 | StringBuilder builder = new StringBuilder(method.getDeclaringClass().getSimpleName());
96 | builder.append('.').append(method.getName()).append('(');
97 | if (method.getParameterTypes() != null) {
98 | for (int i = 0, size = method.getParameterTypes().length; i < size; ++i) {
99 | if (i != 0) builder.append(", ");
100 | builder.append(method.getParameterTypes()[i].getSimpleName());
101 | }
102 | }
103 | builder.append(')');
104 | return builder.toString();
105 | }
106 |
107 | @Override
108 | public String toString() {
109 | return "MethodCallImpl{" +
110 | "method=" + method +
111 | ", logExec=" + logExec +
112 | ", scriptExpr='" + scriptExpr + '\'' +
113 | ", weight=" + weight +
114 | ", serviceName='" + serviceName + '\'' +
115 | '}';
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/exec/support/MethodCallProxyImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.exec.support;
2 |
3 | import com.github.middleware.fsm.builder.exec.dto.RuleExecContext;
4 | import com.github.middleware.fsm.builder.machine.support.AbstractStateMachine;
5 | import com.github.middleware.fsm.builder.StateMachine;
6 | import com.github.middleware.fsm.builder.StateMachines;
7 | import com.github.middleware.fsm.core.utils.Precondition;
8 | import com.github.middleware.fsm.core.utils.ReflectUtil;
9 | import com.github.middleware.fsm.builder.exec.Action;
10 | import org.apache.commons.lang3.StringUtils;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.lang.reflect.Method;
15 |
16 | /**
17 | * 方法调用代理
18 | * TODO:根据方法名支持更多执行策略,比如:ignore/before/after
19 | *
20 | * @author alex.chen
21 | * @version 1.0.0
22 | * @date 2017/3/7
23 | */
24 | public class MethodCallProxyImpl, S, E, C> implements Action {
25 | private static final Logger LOGGER = LoggerFactory.getLogger(MethodCallProxyImpl.class);
26 | private String methodName;
27 | private RuleExecContext execContext;
28 | private Action delegator;
29 | private int weight;
30 | private long timeout;
31 |
32 | /**
33 | * @param methodName
34 | * @param execContext
35 | */
36 | public MethodCallProxyImpl(String methodName, RuleExecContext execContext) {
37 | this.methodName = methodName;
38 | this.execContext = execContext;
39 | this.weight = Action.WEIGHT_NORMAL;
40 | }
41 |
42 | @Override
43 | public void execute(S from, S to, E event, C context, T stateMachine,String actionName) {
44 | Precondition.checkNotNull(stateMachine, "校验异常:状态机实现类不能为空.");
45 | getDelegator().execute(from, to, event, context, stateMachine, actionName);
46 | }
47 |
48 | private Action getDelegator() {
49 | if (delegator == null) {
50 | Method method = ReflectUtil.searchMethod(execContext.getExecutionTargetType(), AbstractStateMachine.class, methodName, execContext.getMethodCallParamTypes());
51 | if (method != null) {
52 | delegator = StateMachines.newMethodCallAction(method, weight, execContext);
53 | } else {
54 | if (LOGGER.isInfoEnabled()) {
55 | LOGGER.info("未找到方法 '" + methodName + "' 参数 '[" + StringUtils.join(execContext.getMethodCallParamTypes(), ", ") + "]' in class " + execContext.getExecutionTargetType() + ".");
56 | }
57 | delegator = (Action) Action.DUMMY_ACTION;
58 | }
59 | }
60 | return delegator;
61 | }
62 |
63 | @Override
64 | public String getName() {
65 | return methodName;
66 | }
67 |
68 | @Override
69 | public int weight() {
70 | return this.weight;
71 | }
72 |
73 | @Override
74 | public long timeout() {
75 | return this.timeout;
76 | }
77 |
78 | @Override
79 | public boolean isAsync() {
80 | return false;
81 | }
82 |
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/StateMachineBuilder.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.chain.LocalTransitionBuilder;
5 | import com.github.middleware.fsm.builder.exec.EntryExitBuilder;
6 | import com.github.middleware.fsm.builder.plugin.PluginBuilder;
7 | import com.github.middleware.fsm.builder.plugin.PluginProvider;
8 | import com.github.middleware.fsm.config.application.StateMachineConfig;
9 |
10 | /**
11 | * @author alex.chen
12 | * @version 1.0.0
13 | * @date 2017/3/6
14 | */
15 | public interface StateMachineBuilder, S, E, C> {
16 | LocalTransitionBuilder localTransition();
17 |
18 | T newStateMachine();
19 |
20 | T newStateMachine(S initialStateName);
21 |
22 | T newStateMachine(S initialStateName, Object... extraParams);
23 |
24 | @Deprecated
25 | T newStateMachine(T fsmBean, S initialStateName, StateMachineConfig configuration, Object... extraParams);
26 |
27 | EntryExitBuilder onEntry(S stateName);
28 |
29 | EntryExitBuilder onExit(S stateName);
30 |
31 | PluginBuilder newPluginBuilder(PluginProvider pluginProvider);
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/annotation/HoldPayload.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * 是否携带Payload
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/3/7
10 | */
11 | @Documented
12 | @Retention(value = RetentionPolicy.RUNTIME)
13 | @Target(ElementType.TYPE)
14 | public @interface HoldPayload {
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/dto/RequestPayload.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.dto;
2 |
3 |
4 | /**
5 | * 请求报文
6 | *
7 | * @author alex.chen
8 | * @version 1.0.0
9 | * @date 2017/2/27
10 | */
11 | @Deprecated
12 | public abstract class RequestPayload {
13 | @Override
14 | public String toString() {
15 | return getRequestPayloadMsg();
16 | }
17 |
18 | public abstract String getRequestPayloadMsg();
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/dto/StateMachineContext.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.dto;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.util.Stack;
7 |
8 | /**
9 | * 状态机上下文环境
10 | *
11 | * @author alex.chen
12 | * @version 1.0.0
13 | * @date 2017/2/27
14 | */
15 | public class StateMachineContext {
16 | private static final Logger LOGGER = LoggerFactory.getLogger(StateMachineContext.class);
17 | private Object currentInstance;
18 | private boolean isTestEvent;
19 |
20 | private StateMachineContext() {
21 | }
22 |
23 | public StateMachineContext(Object stateMachine, boolean isTestEvent) {
24 | this.currentInstance = stateMachine;
25 | this.isTestEvent = isTestEvent;
26 | }
27 |
28 | private static final ThreadLocal> contextContainer = new ThreadLocal>() {
29 | @Override
30 | protected Stack initialValue() {
31 | return new Stack();
32 | }
33 | };
34 |
35 | public static void setTnstance(Object instance) {
36 | setTnstance(instance, false);
37 | }
38 |
39 | public static void setTnstance(Object instance, boolean isTestEvent) {
40 | if (instance == null) {
41 | contextContainer.get().pop();
42 | } else {
43 | contextContainer.get().push(new StateMachineContext(instance, isTestEvent));
44 | }
45 | }
46 |
47 | public static T getTnstance() {
48 | return contextContainer.get().size() > 0 ? (T) contextContainer.get().peek().currentInstance : null;
49 | }
50 |
51 | public static boolean isTestEvent() {
52 | return contextContainer.get().size() > 0 ? contextContainer.get().peek().isTestEvent : false;
53 | }
54 |
55 | public static void removeContext() {
56 | contextContainer.remove();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/factroy/StateMachineBuilderFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.factroy;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 | import com.github.middleware.fsm.builder.machine.StateMachineBuilder;
5 | import com.github.middleware.fsm.builder.machine.support.visit.StateMachineBuilderProxy;
6 | import com.github.middleware.fsm.builder.machine.support.visit.StateMachineProxy;
7 | import com.github.middleware.fsm.config.application.StateMachineConfig;
8 | import com.github.middleware.fsm.core.factory.DependProvider;
9 | import com.github.middleware.fsm.core.types.TypeReference;
10 | import com.github.middleware.fsm.exception.StateMachineException;
11 |
12 | import java.lang.reflect.InvocationHandler;
13 | import java.lang.reflect.InvocationTargetException;
14 | import java.lang.reflect.Method;
15 | import java.lang.reflect.Proxy;
16 |
17 | /**
18 | * @author alex.chen
19 | * @version 1.0.0
20 | * @date 2017/3/6
21 | */
22 | public class StateMachineBuilderFactory {
23 | /**
24 | * 根据ProxyStateMachine来创建
25 | *
26 | * @param fsmClazz
27 | * @return
28 | */
29 | public static StateMachineBuilderProxy create(Class extends StateMachineProxy> fsmClazz) {
30 | return create(fsmClazz, new Class[0]);
31 | }
32 |
33 | /**
34 | * 根据ProxyStateMachine来创建
35 | *
36 | * @param fsmClazz
37 | * @param paramTypes
38 | * @return
39 | */
40 | public static StateMachineBuilderProxy create(Class extends StateMachineProxy> fsmClazz,
41 | Class>... paramTypes) {
42 | final StateMachineBuilder builder =
43 | create(fsmClazz, Object.class, Object.class, Object.class, paramTypes);
44 | return (StateMachineBuilderProxy) Proxy.newProxyInstance(
45 | StateMachineBuilderProxy.class.getClassLoader(),
46 | new Class[]{StateMachineBuilderProxy.class},
47 | new InvocationHandler() {
48 | @Override
49 | public Object invoke(Object proxy, Method method, Object[] args)
50 | throws Throwable {
51 | try {
52 | String methodName = method.getName();
53 | if (methodName.equals("newDefaultStateMachine") || methodName.equals("newSoftStateMachine")) {
54 | Object fsmInstance = null;
55 | if (args.length == 3 && StateMachineConfig.class.isAssignableFrom(args[1].getClass()) &&
56 | (args[2] == null || args[2].getClass().isArray())) {
57 | fsmInstance = builder.newStateMachine(args[0], (StateMachineConfig) args[1], (Object[]) args[2]);
58 | } else if (args.length == 2 && (args[1] == null || args[1].getClass().isArray())) {
59 | fsmInstance = builder.newStateMachine(args[0], (Object[]) args[1]);
60 | } else if (args.length == 1) {
61 | fsmInstance = builder.newStateMachine(args[0]);
62 | } else {
63 | throw new StateMachineException("Illegal argument number.");
64 | }
65 | return fsmInstance;
66 | }
67 | return method.invoke(builder, args);
68 | } catch (InvocationTargetException e) {
69 | throw e.getTargetException();
70 | }
71 | }
72 | });
73 | }
74 |
75 |
76 | /**
77 | * 根据AbstractStateMachine来创建
78 | *
79 | * @param fsmClazz
80 | * @param stateClazz
81 | * @param eventClazz
82 | * @param contextClazz
83 | * @param extraConstParamTypes
84 | * @param
85 | * @param
86 | * @param
87 | * @param
88 | * @return
89 | */
90 | public static , S, E, C> StateMachineBuilder create(
91 | Class extends T> fsmClazz, Class stateClazz, Class eventClazz, Class contextClazz,
92 | Class>... extraConstParamTypes) {
93 | return DependProvider.getInstance().newInstance(new TypeReference>() {
94 | },
95 | new Class[]{Class.class, Class.class, Class.class, Class.class, Class[].class},
96 | new Object[]{fsmClazz, stateClazz, eventClazz, contextClazz, extraConstParamTypes});
97 | }
98 |
99 | public static , S, E, C> StateMachineBuilder create(
100 | Class extends T> stateMachineClazz, Class stateClazz, Class eventClazz, Class contextClazz) {
101 | return create(stateMachineClazz, stateClazz, eventClazz, contextClazz, new Class>[0]);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/support/AbstractSubject.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.support;
2 |
3 | import com.github.middleware.fsm.builder.event.BaseEvent;
4 | import com.github.middleware.fsm.builder.event.dto.ListenerMethod;
5 | import com.google.common.base.Predicate;
6 | import com.google.common.collect.Iterators;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import java.lang.reflect.Method;
11 | import java.util.LinkedHashSet;
12 |
13 | /**
14 | * 向FSM中添加事件监听
15 | *
16 | * @author alex.chen
17 | * @version 1.0.0
18 | * @date 2017/3/8
19 | */
20 | public abstract class AbstractSubject {
21 | private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSubject.class);
22 | private LinkedHashSet listeners = null;
23 |
24 | /**
25 | * 触发事件
26 | *
27 | * @param event
28 | */
29 | protected void fireEvent(BaseEvent event) {
30 | if (listeners == null) return;
31 | ListenerMethod[] listenerArray = listeners.toArray(new ListenerMethod[listeners.size()]);
32 | for (int i = 0; i < listenerArray.length; i++) {
33 | if (listenerArray[i].getEventType().isAssignableFrom(event.getClass())) {
34 | listenerArray[i].invokeMethod(event);
35 | }
36 | }
37 | }
38 |
39 | /**
40 | * 添加事件监听
41 | *
42 | * @param eventType
43 | * @param listener
44 | * @param method
45 | */
46 | protected void addListener(Class> eventType, Object listener, Method method) {
47 | register(eventType, listener, method);
48 | }
49 |
50 | /**
51 | * 删除监听
52 | *
53 | * @param eventType
54 | * @param listener
55 | * @param method
56 | */
57 | protected void removeListener(Class> eventType, Object listener, Method method) {
58 | if (listeners != null) {
59 | ListenerMethod toBeRemove = Iterators.find(listeners.iterator(), new Predicate() {
60 | @Override
61 | public boolean apply(ListenerMethod m) {
62 | return m.matches(eventType, listener, method);
63 | }
64 | });
65 | if (toBeRemove != null) {
66 | listeners.remove(toBeRemove);
67 | }
68 | }
69 | }
70 |
71 | protected void removeListener(Class> eventType, Object listener) {
72 | if (listeners != null) {
73 | Iterators.removeIf(listeners.iterator(), new Predicate() {
74 | @Override
75 | public boolean apply(ListenerMethod m) {
76 | return m.matches(eventType, listener);
77 | }
78 | });
79 | }
80 | }
81 |
82 | /**
83 | * 添加事件监听
84 | *
85 | * @param eventType
86 | * @param listener
87 | * @param method
88 | */
89 | private void register(Class> eventType, Object listener, Method method) {
90 | if (!enableEventListener()) {
91 | LOGGER.warn("addListener失败,未开启相应配置");
92 | return;
93 | }
94 | if (listeners == null) {
95 | listeners = new LinkedHashSet();
96 | }
97 | listeners.add(new ListenerMethod(eventType, listener, method));
98 | }
99 |
100 | protected abstract boolean enableEventListener();
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/support/visit/AbstractStateMachineProxy.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.support.visit;
2 |
3 | import com.github.middleware.fsm.builder.machine.support.AbstractStateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/12
9 | */
10 | public abstract class AbstractStateMachineProxy extends AbstractStateMachine implements StateMachineProxy {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/support/visit/DefaultStateMachineBuilder.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.support.visit;
2 |
3 | import com.github.middleware.fsm.builder.machine.StateMachineBuilder;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/6
9 | */
10 | @Deprecated
11 | public interface DefaultStateMachineBuilder extends StateMachineBuilder {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/support/visit/StateMachineBuilderProxy.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.support.visit;
2 |
3 | import com.github.middleware.fsm.config.application.StateMachineConfig;
4 | import com.github.middleware.fsm.builder.machine.StateMachineBuilder;
5 |
6 | /**
7 | * Created by YT on 2017/3/12.
8 | */
9 | public interface StateMachineBuilderProxy extends StateMachineBuilder {
10 | T newDefaultStateMachine(Object initialStateId);
11 |
12 | T newDefaultStateMachine(Object initialStateId, Object... extraParams);
13 |
14 | T newDefaultStateMachine(
15 | Object initialStateId, StateMachineConfig configuration, Object... extraParams);
16 |
17 | T newSoftStateMachine(Object initialStateId);
18 |
19 | T newSoftStateMachine(Object initialStateId, Object... extraParams);
20 |
21 | T newSoftStateMachine(Object initialStateId, StateMachineConfig configuration, Object... extraParams);
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/github/middleware/fsm/builder/machine/support/visit/StateMachineProxy.java:
--------------------------------------------------------------------------------
1 | package com.github.middleware.fsm.builder.machine.support.visit;
2 |
3 | import com.github.middleware.fsm.builder.StateMachine;
4 |
5 | /**
6 | * @author alex.chen
7 | * @version 1.0.0
8 | * @date 2017/3/12
9 | */
10 | public interface StateMachineProxy extends StateMachine