/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.objecttransaction.state;
import org.eclipse.core.runtime.Assert;
/**
* StateMachine which takes a State, applies an Action on it and the result is a
* new State. If an Action is invalid for a certain State, the
* InvalidActionFailure is thrown.
*
*/
public final class StateMachine {
private StateMachine() {
// utility
}
/**
* Creates an initialState for a given action.
*
* @param action
* for which to create a state
* @return initialState
* @throws InvalidActionFailure
*/
public static State initAction(final Action action) throws InvalidActionFailure {
if (action.equals(Action.NEW) || action.equals(Action.ADD) || action.equals(Action.SET)) {
return State.CREATED;
} else if (action.equals(Action.DELETE) || action.equals(Action.REMOVE)) {
return State.DELETED;
}
throw new InvalidActionFailure("unknown action " + Action.toString(action)); //$NON-NLS-1$
}
/**
* Applies an action on a currentState and returns the resulting State. If
* the Action is invalid for this state an InvalidActionFailure is thrown
*
* @param currentState
* @param action
* @return State this is the new State after applying the action
* @throws InvalidActionFailure
* @pre currentState!=null
*/
public static State processAction(final State currentState, final Action action) throws InvalidActionFailure {
Assert.isNotNull(currentState, "currentState cannot be null"); //$NON-NLS-1$
// CREATED
if (currentState.equals(State.CREATED)) {
if (action.equals(Action.SET) || action.equals(Action.ADD) || action.equals(Action.REMOVE)) {
return currentState;
} else if (action.equals(Action.NEW)) {
return currentState;
} else if (action.equals(Action.DELETE)) {
return State.VANISHED;
}
// MODIFIED
} else if (currentState.equals(State.MODIFIED)) {
if (action.equals(Action.NEW)) {
throw new InvalidActionFailure("state is MODIFIED, can't set to NEW"); //$NON-NLS-1$
} else if (action.equals(Action.SET) || action.equals(Action.ADD) || action.equals(Action.REMOVE)) {
return currentState;
} else if (action.equals(Action.DELETE)) {
return State.DELETED;
}
// DELETED
} else if (currentState.equals(State.DELETED)) {
throw new InvalidActionFailure("currentState is DELETED, no action possible"); //$NON-NLS-1$
// VANISHED
} else if (currentState.equals(State.VANISHED)) {
throw new InvalidActionFailure("currentState is VANISHED, no action possible"); //$NON-NLS-1$
// CLEAN
} else if (currentState.equals(State.CLEAN)) {
if (action.equals(Action.NEW)) {
throw new InvalidActionFailure("state is MODIFIED, can't set to NEW"); //$NON-NLS-1$
} else if (action.equals(Action.SET) || action.equals(Action.ADD) || action.equals(Action.REMOVE)) {
return State.MODIFIED;
} else if (action.equals(Action.DELETE)) {
return State.DELETED;
}
}
throw new InvalidActionFailure(
"unknown action for currentState state is " + State.toString(currentState) + " action is " + Action.toString(action)); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Merges two States and create a resulting State. The newState (second
* parameter) is the more current State that is updating the existing
* current State (first Parameter).
*
* @param currentState
* @param newState
* @return State the new state after the merge
* @throws InvalidActionFailure
*/
public static State mergeStates(final State currentState, final State newState) throws InvalidActionFailure {
if (currentState.equals(newState)) {
return currentState;
}
if (currentState.equals(State.CREATED)) {
if (newState.equals(State.DELETED) || newState.equals(State.VANISHED)) {
return State.VANISHED;
} else {
return State.CREATED;
}
} else if (currentState.equals(State.MODIFIED)
&& (newState.equals(State.DELETED) || newState.equals(State.VANISHED))) {
return State.DELETED;
} else if (currentState.equals(State.MODIFIED) && newState.equals(State.CREATED)) {
return State.MODIFIED;
} else if (currentState.equals(State.DELETED) || currentState.equals(State.VANISHED)) {
throw new InvalidActionFailure(
"current State is " + State.toString(currentState) + " new State is " + State.toString(newState) + " invalid change"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} else if (currentState.equals(State.CLEAN)) {
if (newState.equals(State.MODIFIED) || newState.equals(State.DELETED)) {
return newState;
}
if (newState.equals(State.VANISHED)) {
throw new InvalidActionFailure(
"current State is " + State.toString(currentState) + " new State is " + State.toString(newState) //$NON-NLS-1$ //$NON-NLS-2$
+ " invalid change"); //$NON-NLS-1$
}
}
throw new InvalidActionFailure(
"unknown current State " + State.toString(currentState) + " and new State " + State.toString(newState)); //$NON-NLS-1$ //$NON-NLS-2$
}
}