package org.squirrelframework.foundation.fsm.impl; import com.google.common.base.Function; import com.google.common.collect.Lists; import org.squirrelframework.foundation.component.SquirrelComponent; import org.squirrelframework.foundation.fsm.*; import org.squirrelframework.foundation.fsm.builder.*; import java.util.Collections; import java.util.List; public class DeferBoundActionBuilderImpl<T extends StateMachine<T, S, E, C>, S, E, C> implements DeferBoundActionBuilder<T, S, E, C>, DeferBoundActionFrom<T, S, E, C>, DeferBoundActionTo<T, S, E, C>, On<T, S, E, C>, SquirrelComponent { private final List<DeferBoundActionInfo<T, S, E, C>> deferBoundActionInfoList; private final ExecutionContext executionContext; private S from; private S to; private DeferBoundActionInfo<T, S, E, C> deferBoundActionInfo; private Condition<C> condition; DeferBoundActionBuilderImpl( List<DeferBoundActionInfo<T, S, E, C>> deferBoundActionInfoList, ExecutionContext executionContext) { this.deferBoundActionInfoList = deferBoundActionInfoList; this.executionContext = executionContext; } @Override public void perform(Action<T, S, E, C> action) { if (condition == null) { deferBoundActionInfo.setActions(Collections.singletonList(action)); } else { deferBoundActionInfo.setActions(Collections .singletonList(warpConditionalAction(action))); } } @Override public void perform(List<? extends Action<T, S, E, C>> actions) { if (condition == null) { deferBoundActionInfo.setActions(actions); } else { List<Action<T, S, E, C>> wrapActions = Lists.transform(actions, new Function<Action<T, S, E, C>, Action<T, S, E, C>>() { @Override public Action<T, S, E, C> apply(Action<T, S, E, C> action) { return warpConditionalAction(action); } }); deferBoundActionInfo.setActions(wrapActions); } } @Override public void evalMvel(String expression) { Action<T, S, E, C> action = FSM.newMvelAction(expression, executionContext); perform(action); } @Override public void callMethod(String methodName) { Action<T, S, E, C> action = FSM.newMethodCallActionProxy(methodName, executionContext); perform(action); } @Override public On<T, S, E, C> on(E event) { deferBoundActionInfo = new DeferBoundActionInfo<T, S, E, C>(from, to, event); deferBoundActionInfoList.add(deferBoundActionInfo); return this; } @Override public On<T, S, E, C> onAny() { deferBoundActionInfo = new DeferBoundActionInfo<T, S, E, C>(from, to, null); deferBoundActionInfoList.add(deferBoundActionInfo); return this; } @Override public DeferBoundActionTo<T, S, E, C> to(S to) { this.to = to; return this; } @Override public DeferBoundActionTo<T, S, E, C> toAny() { return this; } @Override public DeferBoundActionFrom<T, S, E, C> fromAny() { return this; } @Override public DeferBoundActionFrom<T, S, E, C> from(S from) { this.from = from; return this; } @Override public When<T, S, E, C> when(Condition<C> condition) { this.condition = condition; return this; } @Override public When<T, S, E, C> whenMvel(String expression) { condition = FSM.newMvelCondition(expression, executionContext.getScriptManager()); return this; } private Action<T, S, E, C> warpConditionalAction(Action<T, S, E, C> action) { return new ActionWrapper<T, S, E, C>(action) { @Override public void execute(S from, S to, E event, C context, T stateMachine) { if (Conditions.isSatified(condition, context)) { super.execute(from, to, event, context, stateMachine); } } }; } }