All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.statusmachina.core.api.Transition Maven / Gradle / Ivy

/*
 *  Copyright 2019 <---> Present Status Machina Contributors (https://github.com/entzik/status-machina/graphs/contributors)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 *  CONDITIONS OF ANY KIND, either express or implied. See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 */

package io.statusmachina.core.api;

import java.util.Optional;

/**
 * Specifies if and how a state machine can transition from one state to another. It matches an edge in the
 * state machine diagram graph.
 * 

* An action can be specified to be executed as part of the transition. If the action throws an exception, the transition * will not be cancelled and the machine will be put in an error state. *

* The transition action can interact with external systems and can mutate the machine's context. *

* transitions can be automatic ( STP: Straight Through Processing ) or event triggered * * @param the state type * @param the event type */ public class Transition { private final S from; private final S to; private final Optional event; private Optional> action; private Optional> postAction; /** * Configure a transition so that if the machine is in a specified current state ("from") and receives the specified * event ("event"), it will move to the specified target state ("to") and execute the specified action in the process. *

* The post action is executed after the transition has completed. if a specific service provider executes the * transition in a transaction, then the post action must be executed after the the transaction has completed and * only if it has completed successfully. * * @param from the current state * @param to the target state * @param event the event that triggers the transition * @param action the action to be executed during the transition * @param postAction the action to be executed after the transition has completed * @param the state type * @param the event type * @return a {@link Transition} instance */ public static Transition event(S from, S to, E event, TransitionAction action, TransitionAction postAction) { return new Transition<>(from, to, event, action, postAction); } /** * Configure a transition so that if the machine is in a specified current state ("from") and receives the specified * event ("event"), it will move to the specified target state ("to") and execute the specified action in the process. * * @param from the current state * @param to the target state * @param event the event that triggers the transition * @param action the action to be executed * @param the state type * @param the event type * @return a {@link Transition} instance */ public static Transition event(S from, S to, E event, TransitionAction action) { return new Transition<>(from, to, event, action); } /** * Configure a transition so that if the machine is in a specified current state ("from") and receives the specified * event ("event"), it will move to the specified target state ("to"). * * @param from the current state * @param to the target state * @param event the event that triggers the transition * @param the state type * @param the event type * @return a {@link Transition} instance */ public static Transition event(S from, S to, E event) { return new Transition<>(from, to, event); } /** * Configure a transition so that if the machine is in a specified current state ("from") it will automatically * move to the specified target state ("to") and execute the specified action in the process. *

* The post action is executed after the transition has completed. If a specific service provider executes the * transition in a transaction, then the post action must be executed after the the transaction has completed and * only if it has completed successfully. * * @param from the current state * @param to the target state * @param action the action to be executed * @param the state type * @param the event type * @return a {@link Transition} instance */ public static Transition stp(S from, S to, TransitionAction action, TransitionAction postAction) { return new Transition<>(from, to, action, postAction); } /** * Configure a transition so that if the machine is in a specified current state ("from") it will automatically * move to the specified target state ("to") and execute the specified action in the process. * * @param from the current state * @param to the target state * @param action the action to be executed * @param the state type * @param the event type * @return a {@link Transition} instance */ public static Transition stp(S from, S to, TransitionAction action) { return new Transition<>(from, to, action); } /** * Configure a transition so that if the machine is in a specified current state ("from") it will automatically * move to the specified target state ("to"). * * @param from the current state * @param to the target state * @param the state type * @param the event type * @return a {@link Transition} instance */ public static Transition stp(S from, S to) { return new Transition<>(from, to); } private Transition(S from, S to, E event, TransitionAction action, TransitionAction postAction) { this.from = from; this.to = to; this.event = Optional.of(event); this.action = Optional.of(action); this.postAction = Optional.of(postAction); } private Transition(S from, S to, E event, TransitionAction action) { this.from = from; this.to = to; this.event = Optional.of(event); this.action = Optional.of(action); this.postAction = Optional.empty(); } private Transition(S from, S to, E event) { this.from = from; this.to = to; this.event = Optional.of(event); this.action = Optional.empty(); this.postAction = Optional.empty(); } private Transition(S from, S to, TransitionAction action, TransitionAction postAction) { this.from = from; this.to = to; this.event = Optional.empty(); this.action = Optional.of(action); this.postAction = Optional.of(postAction); } private Transition(S from, S to, TransitionAction action) { this.from = from; this.to = to; this.event = Optional.empty(); this.action = Optional.of(action); this.postAction = Optional.empty(); } private Transition(S from, S to) { this.from = from; this.to = to; this.event = Optional.empty(); this.action = Optional.empty(); this.postAction = Optional.empty(); } /** * return the state in which the state machine needs to be in order for this transition to activate (if all other * conditions are fulfilled) * * @return the state */ public S getFrom() { return from; } /** * return the state in which this transition will end up should this transition activate and cbe carried over successfully * * @return the target state */ public S getTo() { return to; } /** * returns the event that needs to be sent to the state machine in order to trigger this transition (should all other * conditions be fulfilled) * * @return the event */ public Optional getEvent() { return event; } /** * @return true if this is an STP action, false otherwise */ public boolean isSTP() { return !event.isPresent(); } /** * @return the action to be executed as part of the transition, should one be configured */ public Optional> getAction() { return action; } /** * @return an action to be executed after a the transition has completed and all state and context changes have been * commited to underlying storage, along with change of any transactional service the action may have invoked. */ public Optional> getPostAction() { return postAction; } }