Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automata4j-API: Fix javadoc and code enhancements #4

Merged
merged 14 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.avrsandbox.fsa.core.state.AutoState;
import com.avrsandbox.fsa.core.state.CloneType;
import com.avrsandbox.fsa.core.state.TransitionListener;
import com.avrsandbox.fsa.util.AutomataLogger;

/**
* A tech-demo demonstrating a basic example of an antegrade finite-state-automaton design pattern.
Expand Down Expand Up @@ -70,7 +71,9 @@ public SerialAdder() {
* Initializes the AutoStates and assigns the entry state.
*/
public void init() {

/* enables automata logger */
AutomataLogger.setEnabled(true);

/* create bits to add */
adders.add(new BitsAdder(0, 0));
adders.add(new BitsAdder(0, 1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import com.avrsandbox.fsa.core.TransitionalManager;
import com.avrsandbox.fsa.core.deterministic.DeterministicManager;
import com.avrsandbox.fsa.core.state.AutoState;
import com.avrsandbox.fsa.core.state.TransitionListener;
import com.avrsandbox.fsa.util.AutomataLogger;
import com.avrsandbox.fsa.util.TransitionPath;

/**
Expand All @@ -44,6 +46,7 @@
*/
public final class TestDeterministicFiniteState {
public static void main(String[] args) {
AutomataLogger.setEnabled(true);

final ArmatureState idleState = new ArmatureState();
idleState.setInput("Idle");
Expand All @@ -57,9 +60,13 @@ public static void main(String[] args) {

final TransitionalManager transitionalManager = new DeterministicManager();
/* repeat the transition path to assert the TransitionPathNotUniqueException */
transitionalManager.transit(transitionPath, null);

transitionalManager.transit(transitionPath, null);
transitionalManager.transit(transitionPath, new TransitionListener() {
@Override
public <I, O> void onTransition(AutoState<I, O> presentState) {
transitionalManager.transit(null);
transitionalManager.transit(transitionPath, null);
}
});
}

protected static final class ArmatureState implements AutoState<String, String> {
Expand All @@ -74,7 +81,7 @@ public void onStart() {

@Override
public void invoke(String input) {
tracer = "Armature is " + input;
tracer = "Armature is " + this.input;
System.out.println(tracer);
}

Expand Down
20 changes: 10 additions & 10 deletions automata4j/src/main/java/com/avrsandbox/fsa/core/Transition.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@

import com.avrsandbox.fsa.core.state.AutoState;
import com.avrsandbox.fsa.core.state.NextStateNotFoundException;
import com.avrsandbox.fsa.core.state.TransitionListener;

/**
* Represents a machine system transition with one next-state {@link Transition#nextState}.
*
*
* @param <S> a type of {@link AutoState}
* @author pavl_g
*/
public final class Transition<S extends AutoState<?, ?>> {
@SuppressWarnings("rawtypes")
public final class Transition<S extends AutoState> {

private S nextState;

Expand All @@ -61,26 +62,25 @@ public Transition(S nextState) {

/**
* Assigns a next-state into your heap memory.
* Default value is (null).
* Default value is (not-null).
*
* @param nextState the next-state object to assign
* @throws NextStateNotFoundException thrown if the next-state is null
*/
public void setNextState(S nextState) {
/* a business exception if there is no next-state assigned */
if (nextState == null) {
throw new NextStateNotFoundException();
}
this.nextState = nextState;
}

/**
* Loads the state from your heap into your stack memory.
*
* @return the next state of the transition system
* @throws NextStateNotFoundException thrown if the {@link TransitionalManager#transit(Object, TransitionListener)}
* is called without assigning a next state
*/
public S getNextState() throws NextStateNotFoundException {
/* a business exception if there is no next-state assigned */
if (nextState == null) {
throw new NextStateNotFoundException();
}
return nextState;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
package com.avrsandbox.fsa.core;

import java.util.logging.Level;
import java.util.logging.Logger;
import java.lang.Thread;
import com.avrsandbox.fsa.core.state.AutoState;
import com.avrsandbox.fsa.core.state.NextStateNotFoundException;
import com.avrsandbox.fsa.core.state.TransitionListener;
import com.avrsandbox.fsa.util.AutomataLogger;
import com.avrsandbox.fsa.util.TransitionPath;

/**
Expand All @@ -56,28 +57,36 @@ public class TransitionalManager {
protected final Transition<AutoState<?, ?>> transition = new Transition<>();

/**
* A general purpose logger for this manager object.
* Instantiates a transitional manager object.
*/
protected static final Logger logger = Logger.getLogger(TransitionalManager.class.getName());

public TransitionalManager() {
}

/**
* Assigns a new next state.
*
* <p>
* Warning: calling this multiple times on different objects
* will override the previous one !
*
* will override the previous one!
* </p>
*
* @param <I> the state input type
* @param <O> the tracer object type
* @param autostate the target state
* @param autoState the target state
*/
public <I, O> void assignNextState(AutoState<I, O> autostate) {
transition.setNextState(autostate);
logger.log(Level.INFO, "Assigned a new state " + autostate);
public <I, O> void assignNextState(AutoState<I, O> autoState) {
transition.setNextState(autoState);
AutomataLogger.log(Level.INFO, TransitionalManager.class.getName(), "assignNextState(AutoState)",
"Assigned a new state " + autoState);
}

/**
* Assigns a new next state from a system transition.
*
* <p>
* Warning: calling this multiple times on different objects
* will override the previous one !
* will override the previous one!
* </p>
*
* @param <I> the state input type
* @param <O> the tracer object type
Expand All @@ -88,17 +97,33 @@ public <I, O> void assignNextState(final Transition<AutoState<I, O>> transition)
}

/**
* Transits to the next-state from a state-transitionPath.
* Traverses through a transition path starting from the present-state
* assigning the next-state without transiting to it.
*
* <p>
* Tips: A call to {@link TransitionalManager#transit(TransitionListener)} can be submitted from the
* {@link TransitionListener#onTransition(AutoState)} to transit to the assigned next-state.
* </p>
*
* @param <I> the state input type
* @param <O> the state tracer object type
* @param transitionPath the system state-transitionPath holding a presentstate and a nextstate
* @param transitionPath the system state-transitionPath holding a present state and a next state
* @param transitionListener an event driven interface object that fires {@link TransitionListener#onTransition(AutoState)}
* after the {@link AutoState#invoke(Object)} is invoked when the transition completes
* after the {@link AutoState#invoke(Object)} is invoked when the transition to the present-state completes
*/
public <I, O> void transit(final TransitionPath<AutoState<I, O>> transitionPath, final TransitionListener transitionListener) {
assignNextState(transitionPath.getNextState());
transit(transitionPath.getNextState().getInput(), transitionListener);
assignNextState(transitionPath.getPresentState());
transit(transitionPath.getPresentState().getInput(), new TransitionListener() {
@Override
@SuppressWarnings("all")
public <I, O> void onTransition(AutoState<I, O> presentState) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

56% of developers fix this issue

TypeParameterShadowing: Found aliased type parameters: I declared in transit


ℹ️ Expand to see all @sonatype-lift commands

You can reply with the following commands. For example, reply with @sonatype-lift ignoreall to leave out all findings.

Command Usage
@sonatype-lift ignore Leave out the above finding from this PR
@sonatype-lift ignoreall Leave out all the existing findings from this PR
@sonatype-lift exclude <file|issue|path|tool> Exclude specified file|issue|path|tool from Lift findings by updating your config.toml file

Note: When talking to LiftBot, you need to refresh the page to see its response.
Click here to add LiftBot to another repo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sonatype-lift ignore

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've recorded this as ignored for this pull request.
If you change your mind, just comment @sonatype-lift unignore.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a critical type shadowing because this is not a user code, so no operations are performed using these type parameters and they got erased to the super-type Object in compile time.

assignNextState(transitionPath.getNextState());
/* incremental dispatch */
if (transitionListener != null) {
transitionListener.onTransition(presentState);
}
}
});
}

/**
Expand All @@ -107,7 +132,7 @@ public <I, O> void transit(final TransitionPath<AutoState<I, O>> transitionPath,
* @param <I> the state input type
* @param <O> the state tracer object type
* @param time the latency after which the transition starts
* @param transitionPath the system state-transitionPath holding a presentstate and a nextstate
* @param transitionPath the system state-transitionPath holding a present state and a next state
* @param transitionListener an event driven interface object that fires {@link TransitionListener#onTransition(AutoState)}
* after the {@link AutoState#invoke(Object)} is invoked when the transition completes
* @throws InterruptedException thrown if the application has interrupted the system during the latency period
Expand Down Expand Up @@ -141,12 +166,14 @@ public <I> void transit(final long time, final I input, final TransitionListener
* @param input the state input
* @param transitionListener an event driven interface object that fires {@link TransitionListener#onTransition(AutoState)}
* after the {@link AutoState#invoke(Object)} is invoked when the transition completes
* @throws NullPointerException thrown if a pointer to the next state is not found
* @throws NextStateNotFoundException thrown if a pointer to the next state is not found
*/
@SuppressWarnings("unchecked")
public <I, O> void transit(final I input, final TransitionListener transitionListener) throws NullPointerException {
public <I, O> void transit(final I input, final TransitionListener transitionListener) throws NextStateNotFoundException {
final AutoState<I, O> autoState = (AutoState<I, O>) transition.getNextState();
logger.log(Level.INFO, "Transiting into a new state " + autoState);
AutomataLogger.log(Level.INFO, TransitionalManager.class.getName(),
"transit(Input, TransitionalListener)", "Transiting into a new state " + autoState);
autoState.setInput(input);
autoState.onStart();
autoState.invoke(input);
if (transitionListener != null) {
Expand All @@ -155,6 +182,19 @@ public <I, O> void transit(final I input, final TransitionListener transitionLis
autoState.onFinish();
}

/**
* Transits to the next assigned state with the predefined input value.
*
* @param transitionListener an event driven interface object that fires {@link TransitionListener#onTransition(AutoState)}
* after the {@link AutoState#invoke(Object)} is invoked when the transition completes
* @param <I> the state input type
* @param <O> the tracer object type
* @throws NextStateNotFoundException thrown if a pointer to the next state is not found
*/
public <I, O> void transit(final TransitionListener transitionListener) {
transit(transition.getNextState().getInput(), transitionListener);
}

/**
* Retrieves the system transition for debugging purposes only.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
*
* @author pavl_g
*/
@SuppressWarnings("rawtypes")
public class DeterministicManager extends TransitionalManager {

/**
Expand All @@ -57,6 +58,13 @@ public class DeterministicManager extends TransitionalManager {
*/
protected Map<String, TransitionPath> paths = new HashMap<>();

/**
* Instantiates a deterministic finite-state-automaton manager that
* defines a single a-successor path (unique transition paths).
*/
public DeterministicManager() {
}

@Override
public <I, O> void transit(TransitionPath<AutoState<I, O>> transitionPath, TransitionListener transitionListener) {
if (hasTransitionPath(transitionPath)) {
Expand All @@ -83,10 +91,11 @@ protected <I, O> boolean hasTransitionPath(TransitionPath<AutoState<I, O>> trans
if (transitionPath == null) {
throw new IllegalArgumentException("Cannot accept null transition paths!");
}
return paths.get(transitionPath.getName()) != null &&
(paths.get(transitionPath.getName()) == transitionPath ||
(paths.get(transitionPath.getName()).getPresentState().hashCode() == transitionPath.getPresentState().hashCode() &&
paths.get(transitionPath.getName()).getNextState().hashCode() == transitionPath.getNextState().hashCode() &&
paths.get(transitionPath.getName()).getNextState().getInput().hashCode() == transitionPath.getNextState().getInput().hashCode()));
TransitionPath transitionPath1 = paths.get(transitionPath.getName());
return transitionPath1 != null &&
(transitionPath1.hashCode() == transitionPath.hashCode() ||
(transitionPath1.getPresentState().hashCode() == transitionPath.getPresentState().hashCode() &&
transitionPath1.getNextState().hashCode() == transitionPath.getNextState().hashCode() &&
transitionPath1.getNextState().getInput().hashCode() == transitionPath.getNextState().getInput().hashCode()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@
import com.avrsandbox.fsa.core.TransitionalManager;

/**
* Loaded into the stack and disptached as a result of trying to call {@link TransitionalManager#transit(Object, TransitionListener)}
* without assigning a next state or as a result of removing the state from the heap before transitting the system.
* Loaded into the stack and dispatched as a result of trying to call {@link TransitionalManager#transit(Object, TransitionListener)}
* without assigning a next state or as a result of removing the state from the heap before transiting the system.
*
* @author pavl_g
*/
public class NextStateNotFoundException extends NullPointerException {

/**
* Instantiates a new exception as a result of transitting into an empty next-state.
* Instantiates a new exception as a result of transiting into an empty next-state.
*/
public NextStateNotFoundException() {
super("Next-State of the transition is not found !");
super("Next-State of the transition is not found!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
public interface TransitionListener {

/**
* Dispatched as a result of commiting a call to {@link TransitionalManager#transit(Object, TransitionListener)}.
* Dispatched as a result of committing a call to {@link TransitionalManager#transit(Object, TransitionListener)}.
*
* Applications should decide how they want to transit to other states from here by selectively assigning them
* based on some system conditions, the API provides a carrier for these system conditions on the tracer object
Expand Down
Loading