Initial config error model and spi

- Move into a generic fail fast configuration error
  model with better exception messages.
- Initial move into a public SPI for state machine
  configuration pojo classes.
- new StateMachineModelVerifier interface for generic model verifying.
- Relates #103
- Relates #172
- Work is done together for above issues mostly because they
  relate to each others for config error handling. Meaning
  we can't really verify configuration if we don't have
  a proper model describing actual config model.
This commit is contained in:
Janne Valkealahti
2016-02-13 15:32:18 +00:00
parent 3ea89d14da
commit ebfa86a0ca
37 changed files with 1097 additions and 336 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,11 +37,16 @@ import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.builders.StateMachineTransitions.ChoiceData;
import org.springframework.statemachine.config.builders.StateMachineTransitions.TransitionData;
import org.springframework.statemachine.config.model.ChoiceData;
import org.springframework.statemachine.config.model.DefaultStateMachineModel;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.statemachine.config.model.TransitionData;
import org.springframework.statemachine.config.model.verifier.CompositeStateMachineModelVerifier;
import org.springframework.statemachine.config.model.verifier.StateMachineModelVerifier;
import org.springframework.statemachine.ensemble.DistributedStateMachine;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.region.Region;
@@ -97,6 +102,10 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
private String beanName;
// TODO: we want to make this configurable via annotation model
// so that user can turn it off or customise
private final StateMachineModelVerifier<S, E> verifier = new CompositeStateMachineModelVerifier<S, E>();
/**
* Instantiates a new enum state machine factory.
*
@@ -119,6 +128,9 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
@SuppressWarnings("unchecked")
@Override
public StateMachine<S, E> getStateMachine() {
// TODO: should pass model into constructor
StateMachineModel<S, E> model = new DefaultStateMachineModel<>(stateMachineConfigurationConfig, stateMachineStates, stateMachineTransitions);
verifier.verify(model);
// shared
DefaultExtendedState defaultExtendedState = new DefaultExtendedState();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,9 +26,9 @@ import org.springframework.statemachine.ExtendedState;
import org.springframework.statemachine.ObjectStateMachine;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.statemachine.region.Region;
import org.springframework.statemachine.state.ObjectState;
import org.springframework.statemachine.state.PseudoState;

View File

@@ -21,17 +21,17 @@ import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineException;
import org.springframework.statemachine.config.builders.StateMachineConfigBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AnnotationBuilder;
import org.springframework.statemachine.config.common.annotation.ObjectPostProcessor;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
/**
* {@code StateMachineBuilder} provides a builder pattern for

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,9 @@
*/
package org.springframework.statemachine.config;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
public class StateMachineConfig<S, E> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,9 @@ package org.springframework.statemachine.config.builders;
import org.springframework.statemachine.config.StateMachineConfig;
import org.springframework.statemachine.config.common.annotation.AbstractConfiguredAnnotationBuilder;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
public class StateMachineConfigBuilder<S, E>
extends

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@ import org.springframework.statemachine.config.configurers.DefaultDistributedSta
import org.springframework.statemachine.config.configurers.DefaultSecurityConfigurer;
import org.springframework.statemachine.config.configurers.DistributedStateMachineConfigurer;
import org.springframework.statemachine.config.configurers.SecurityConfigurer;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.ensemble.StateMachineEnsemble;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.security.SecurityRule;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,12 +18,13 @@ package org.springframework.statemachine.config.builders;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.statemachine.config.StateData;
import org.springframework.statemachine.config.common.annotation.AbstractConfiguredAnnotationBuilder;
import org.springframework.statemachine.config.common.annotation.AnnotationBuilder;
import org.springframework.statemachine.config.common.annotation.ObjectPostProcessor;
import org.springframework.statemachine.config.configurers.DefaultStateConfigurer;
import org.springframework.statemachine.config.configurers.StateConfigurer;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineStates;
/**
* {@link AnnotationBuilder} for {@link StateMachineStates}.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,6 @@ import java.util.List;
import java.util.Map;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.builders.StateMachineTransitions.ChoiceData;
import org.springframework.statemachine.config.builders.StateMachineTransitions.TransitionData;
import org.springframework.statemachine.config.common.annotation.AbstractConfiguredAnnotationBuilder;
import org.springframework.statemachine.config.common.annotation.AnnotationBuilder;
import org.springframework.statemachine.config.common.annotation.ObjectPostProcessor;
@@ -39,6 +37,10 @@ import org.springframework.statemachine.config.configurers.ForkTransitionConfigu
import org.springframework.statemachine.config.configurers.InternalTransitionConfigurer;
import org.springframework.statemachine.config.configurers.JoinTransitionConfigurer;
import org.springframework.statemachine.config.configurers.LocalTransitionConfigurer;
import org.springframework.statemachine.config.model.ChoiceData;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.statemachine.config.model.TransitionData;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.security.SecurityRule;
import org.springframework.statemachine.transition.TransitionKind;

View File

@@ -1,271 +0,0 @@
/*
* Copyright 2015 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.builders;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.security.SecurityRule;
import org.springframework.statemachine.transition.TransitionKind;
/**
* Data object for transitions.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class StateMachineTransitions<S, E> {
private final Collection<TransitionData<S, E>> transitions;
private final Map<S, List<ChoiceData<S, E>>> choices;
private final Map<S, List<S>> forks;
private final Map<S, List<S>> joins;
/**
* Instantiates a new state machine transitions.
*
* @param transitions the transitions
* @param choices the choices
* @param forks the forks
* @param joins the joins
*/
public StateMachineTransitions(Collection<TransitionData<S, E>> transitions,
Map<S, List<ChoiceData<S, E>>> choices, Map<S, List<S>> forks, Map<S, List<S>> joins) {
this.transitions = transitions;
this.choices = choices;
this.forks = forks;
this.joins = joins;
}
/**
* Gets the transitions.
*
* @return the transitions
*/
public Collection<TransitionData<S, E>> getTransitions() {
return transitions;
}
/**
* Gets the choices.
*
* @return the choices
*/
public Map<S, List<ChoiceData<S, E>>> getChoices() {
return choices;
}
/**
* Gets the forks.
*
* @return the forks
*/
public Map<S, List<S>> getForks() {
return forks;
}
/**
* Gets the joins.
*
* @return the joins
*/
public Map<S, List<S>> getJoins() {
return joins;
}
/**
* A simple data object keeping transition related configs in a same place.
*
* @param <S> the type of state
* @param <E> the type of event
*/
public static class TransitionData<S, E> {
private final S source;
private final S target;
private final S state;
private final E event;
private final Long period;
private final Collection<Action<S, E>> actions;
private final Guard<S, E> guard;
private final TransitionKind kind;
private final SecurityRule securityRule;
/**
* Instantiates a new transition data.
*
* @param source the source
* @param target the target
* @param state the state
* @param event the event
* @param period the period
* @param actions the actions
* @param guard the guard
* @param kind the kind
* @param securityRule the security rule
*/
public TransitionData(S source, S target, S state, E event, Long period, Collection<Action<S, E>> actions,
Guard<S, E> guard, TransitionKind kind, SecurityRule securityRule) {
this.source = source;
this.target = target;
this.state = state;
this.event = event;
this.period = period;
this.actions = actions;
this.guard = guard;
this.kind = kind;
this.securityRule = securityRule;
}
/**
* Gets the source.
*
* @return the source
*/
public S getSource() {
return source;
}
/**
* Gets the target.
*
* @return the target
*/
public S getTarget() {
return target;
}
/**
* Gets the state.
*
* @return the state
*/
public S getState() {
return state;
}
/**
* Gets the event.
*
* @return the event
*/
public E getEvent() {
return event;
}
/**
* Gets the period.
*
* @return the period
*/
public Long getPeriod() {
return period;
}
/**
* Gets the actions.
*
* @return the actions
*/
public Collection<Action<S, E>> getActions() {
return actions;
}
/**
* Gets the guard.
*
* @return the guard
*/
public Guard<S, E> getGuard() {
return guard;
}
/**
* Gets the kind.
*
* @return the kind
*/
public TransitionKind getKind() {
return kind;
}
/**
* Gets the security rule.
*
* @return the security rule
*/
public SecurityRule getSecurityRule() {
return securityRule;
}
}
/**
* A simple data object keeping choice related configs in a same place.
*
* @param <S> the type of state
* @param <E> the type of event
*/
public static class ChoiceData<S, E> {
private final S source;
private final S target;
private final Guard<S, E> guard;
/**
* Instantiates a new choice data.
*
* @param source the source
* @param target the target
* @param guard the guard
*/
public ChoiceData(S source, S target, Guard<S, E> guard) {
this.source = source;
this.target = target;
this.guard = guard;
}
/**
* Gets the source.
*
* @return the source
*/
public S getSource() {
return source;
}
/**
* Gets the target.
*
* @return the target
*/
public S getTarget() {
return target;
}
/**
* Gets the guard.
*
* @return the guard
*/
public Guard<S, E> getGuard() {
return guard;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,12 +35,12 @@ import org.springframework.statemachine.config.ObjectStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfig;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AbstractImportingAnnotationConfiguration;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurer;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,11 +37,11 @@ import org.springframework.statemachine.config.StateMachineConfig;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.config.builders.StateMachineConfigBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AbstractImportingAnnotationConfiguration;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurer;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.util.ClassUtils;
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.security.SecurityRule;
import org.springframework.statemachine.security.SecurityRule.ComparisonType;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,9 @@ import java.util.List;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.builders.StateMachineTransitions.ChoiceData;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.ChoiceData;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.statemachine.guard.Guard;
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.listener.StateMachineListener;
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
package org.springframework.statemachine.config.configurers;
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.ensemble.StateMachineEnsemble;
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ import java.util.List;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineTransitions;
/**
* Default implementation of a {@link ForkTransitionConfigurer}.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@ import java.util.List;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineTransitions;
/**
* Default implementation of a {@link JoinTransitionConfigurer}.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,9 @@ package org.springframework.statemachine.config.configurers;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.security.SecurityRule;
import org.springframework.statemachine.security.SecurityRule.ComparisonType;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,11 +24,11 @@ import java.util.Set;
import java.util.UUID;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.StateData;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.state.PseudoStateKind;
/**

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model;
import org.springframework.statemachine.guard.Guard;
/**
* A simple data object keeping choice related configs in a same place.
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class ChoiceData<S, E> {
private final S source;
private final S target;
private final Guard<S, E> guard;
/**
* Instantiates a new choice data.
*
* @param source the source
* @param target the target
* @param guard the guard
*/
public ChoiceData(S source, S target, Guard<S, E> guard) {
this.source = source;
this.target = target;
this.guard = guard;
}
/**
* Gets the source.
*
* @return the source
*/
public S getSource() {
return source;
}
/**
* Gets the target.
*
* @return the target
*/
public S getTarget() {
return target;
}
/**
* Gets the guard.
*
* @return the guard
*/
public Guard<S, E> getGuard() {
return guard;
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model;
/**
* Default implementation of a {@link StateMachineModel}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class DefaultStateMachineModel<S, E> extends StateMachineModel<S, E> {
private final StateMachineConfigurationConfig<S, E> configuration;
private final StateMachineStates<S, E> states;
private final StateMachineTransitions<S, E> transitions;
/**
* Instantiates a new default state machine model.
*
* @param configuration the configuration
* @param states the states
* @param transitions the transitions
*/
public DefaultStateMachineModel(StateMachineConfigurationConfig<S, E> configuration, StateMachineStates<S, E> states,
StateMachineTransitions<S, E> transitions) {
this.configuration = configuration;
this.states = states;
this.transitions = transitions;
}
@Override
public StateMachineConfigurationConfig<S, E> getConfiguration() {
return configuration;
}
@Override
public StateMachineStates<S, E> getStates() {
return states;
}
@Override
public StateMachineTransitions<S, E> getTransitions() {
return transitions;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model;
import java.io.IOException;
import org.springframework.statemachine.StateMachineException;
/**
* Generic exception indicating ill-formed state machine configuration.
*
* @author Janne Valkealahti
*
*/
public class MalformedConfigurationException extends StateMachineException {
private static final long serialVersionUID = -1658322647044177891L;
private StringBuilder trace;
/**
* Instantiates a new malformed configuration exception.
*
* @param e the e
*/
public MalformedConfigurationException(IOException e) {
super(e);
}
/**
* Instantiates a new malformed configuration exception.
*
* @param message the message
* @param e the e
*/
public MalformedConfigurationException(String message, Exception e) {
super(message, e);
}
/**
* Instantiates a new malformed configuration exception.
*
* @param message the message
* @param cause the cause
*/
public MalformedConfigurationException(String message, Throwable cause) {
super(message, cause);
}
/**
* Instantiates a new malformed configuration exception.
*
* @param message the message
*/
public MalformedConfigurationException(String message) {
super(message);
}
/**
* Instantiates a new malformed configuration exception.
*
* @param message the message
* @param infos the infos
*/
public MalformedConfigurationException(String message, String... infos) {
super(message);
for (String info : infos) {
addTrace(info);
}
}
@Override
public String getMessage() {
if (trace == null) return super.getMessage();
StringBuilder buffer = new StringBuilder(512);
buffer.append(super.getMessage());
if (buffer.length() > 0) {
buffer.append('\n');
}
buffer.append("Statemachine trace:");
buffer.append(trace);
return buffer.toString();
}
/**
* Adds a trace info into this exception.
*
* @param info the info
*/
public void addTrace(String info) {
if (info == null) {
throw new IllegalArgumentException("info cannot be null.");
}
if (trace == null) {
trace = new StringBuilder(256);
}
trace.append('\n');
trace.append(info);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.config;
package org.springframework.statemachine.config.model;
import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.state.PseudoStateKind;
import org.springframework.statemachine.state.State;
@@ -61,7 +62,7 @@ public class StateData<S, E> {
public Collection<E> getDeferred() {
return deferred;
}
public void setDeferred(Collection<E> deferred) {
this.deferred = deferred;
}
@@ -69,7 +70,7 @@ public class StateData<S, E> {
public Collection<? extends Action<S, E>> getEntryActions() {
return entryActions;
}
public void setEntryActions(Collection<? extends Action<S, E>> entryActions) {
this.entryActions = entryActions;
}
@@ -77,7 +78,7 @@ public class StateData<S, E> {
public Collection<? extends Action<S, E>> getExitActions() {
return exitActions;
}
public void setExitActions(Collection<? extends Action<S, E>> exitActions) {
this.exitActions = exitActions;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.config.builders;
package org.springframework.statemachine.config.model;
import java.util.List;
@@ -21,6 +21,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.ensemble.StateMachineEnsemble;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.security.SecurityRule;

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model;
/**
* Base abstract SPI class for state machine configuration.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public abstract class StateMachineModel<S, E> {
/**
* Gets the configuration config.
*
* @return the configuration config
*/
public abstract StateMachineConfigurationConfig<S, E> getConfiguration();
/**
* Gets the states config.
*
* @return the states config
*/
public abstract StateMachineStates<S, E> getStates();
/**
* Gets the transitions config.
*
* @return the transitions config
*/
public abstract StateMachineTransitions<S, E> getTransitions();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.config.builders;
package org.springframework.statemachine.config.model;
import java.util.Collection;
import org.springframework.statemachine.config.StateData;
import org.springframework.statemachine.config.configurers.StateConfigurer;
/**

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Data object for transitions.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class StateMachineTransitions<S, E> {
private final Collection<TransitionData<S, E>> transitions;
private final Map<S, List<ChoiceData<S, E>>> choices;
private final Map<S, List<S>> forks;
private final Map<S, List<S>> joins;
/**
* Instantiates a new state machine transitions.
*
* @param transitions the transitions
* @param choices the choices
* @param forks the forks
* @param joins the joins
*/
public StateMachineTransitions(Collection<TransitionData<S, E>> transitions,
Map<S, List<ChoiceData<S, E>>> choices, Map<S, List<S>> forks, Map<S, List<S>> joins) {
this.transitions = transitions;
this.choices = choices;
this.forks = forks;
this.joins = joins;
}
/**
* Gets the transitions.
*
* @return the transitions
*/
public Collection<TransitionData<S, E>> getTransitions() {
return transitions;
}
/**
* Gets the choices.
*
* @return the choices
*/
public Map<S, List<ChoiceData<S, E>>> getChoices() {
return choices;
}
/**
* Gets the forks.
*
* @return the forks
*/
public Map<S, List<S>> getForks() {
return forks;
}
/**
* Gets the joins.
*
* @return the joins
*/
public Map<S, List<S>> getJoins() {
return joins;
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model;
import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.security.SecurityRule;
import org.springframework.statemachine.transition.TransitionKind;
/**
* A simple data object keeping transition related configs in a same place.
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class TransitionData<S, E> {
private final S source;
private final S target;
private final S state;
private final E event;
private final Long period;
private final Collection<Action<S, E>> actions;
private final Guard<S, E> guard;
private final TransitionKind kind;
private final SecurityRule securityRule;
/**
* Instantiates a new transition data.
*
* @param source the source
* @param target the target
* @param state the state
* @param event the event
* @param period the period
* @param actions the actions
* @param guard the guard
* @param kind the kind
* @param securityRule the security rule
*/
public TransitionData(S source, S target, S state, E event, Long period, Collection<Action<S, E>> actions,
Guard<S, E> guard, TransitionKind kind, SecurityRule securityRule) {
this.source = source;
this.target = target;
this.state = state;
this.event = event;
this.period = period;
this.actions = actions;
this.guard = guard;
this.kind = kind;
this.securityRule = securityRule;
}
/**
* Gets the source.
*
* @return the source
*/
public S getSource() {
return source;
}
/**
* Gets the target.
*
* @return the target
*/
public S getTarget() {
return target;
}
/**
* Gets the state.
*
* @return the state
*/
public S getState() {
return state;
}
/**
* Gets the event.
*
* @return the event
*/
public E getEvent() {
return event;
}
/**
* Gets the period.
*
* @return the period
*/
public Long getPeriod() {
return period;
}
/**
* Gets the actions.
*
* @return the actions
*/
public Collection<Action<S, E>> getActions() {
return actions;
}
/**
* Gets the guard.
*
* @return the guard
*/
public Guard<S, E> getGuard() {
return guard;
}
/**
* Gets the kind.
*
* @return the kind
*/
public TransitionKind getKind() {
return kind;
}
/**
* Gets the security rule.
*
* @return the security rule
*/
public SecurityRule getSecurityRule() {
return securityRule;
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model.verifier;
import java.util.Iterator;
import org.springframework.statemachine.config.model.MalformedConfigurationException;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.support.tree.Tree;
import org.springframework.statemachine.support.tree.Tree.Node;
import org.springframework.statemachine.support.tree.TreeTraverser;
/**
* {@link StateMachineModelVerifier} which verifies a base model structure
* like existence of initial states, etc.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class BaseStructureVerifier<S, E> implements StateMachineModelVerifier<S, E> {
@Override
public void verify(StateMachineModel<S, E> model) {
// TODO: just a base root initial state check for now
// further development needed
Iterator<Node<StateData<S, E>>> iterator = buildStateDataIterator(model.getStates());
while (iterator.hasNext()) {
Node<StateData<S, E>> node = iterator.next();
if (node.getData() == null) {
boolean initialStateFound = false;
for (Node<StateData<S, E>> n : node.getChildren()) {
StateData<S, E> data = n.getData();
if (data.isInitial()) {
initialStateFound = true;
}
}
if (!initialStateFound) {
MalformedConfigurationException exception = new MalformedConfigurationException("Initial state not set");
for (Node<StateData<S, E>> c : node.getChildren()) {
exception.addTrace(c.getData().toString());
}
throw exception;
}
}
}
}
private Iterator<Node<StateData<S, E>>> buildStateDataIterator(StateMachineStates<S, E> stateMachineStates) {
Tree<StateData<S, E>> tree = new Tree<StateData<S, E>>();
for (StateData<S, E> stateData : stateMachineStates.getStateDatas()) {
Object id = stateData.getState();
Object parent = stateData.getParent();
tree.add(stateData, id, parent);
}
TreeTraverser<Node<StateData<S, E>>> traverser = new TreeTraverser<Node<StateData<S, E>>>() {
@Override
public Iterable<Node<StateData<S, E>>> children(Node<StateData<S, E>> root) {
return root.getChildren();
}
};
Iterable<Node<StateData<S, E>>> postOrderTraversal = traverser.postOrderTraversal(tree.getRoot());
Iterator<Node<StateData<S, E>>> iterator = postOrderTraversal.iterator();
return iterator;
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model.verifier;
import java.util.Iterator;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.support.AbstractCompositeItems;
/**
* Implementation of a {@link StateMachineModelVerifier} backed by a multiple verifiers.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class CompositeStateMachineModelVerifier<S, E> extends AbstractCompositeItems<StateMachineModelVerifier<S, E>>
implements StateMachineModelVerifier<S, E> {
public CompositeStateMachineModelVerifier() {
super();
register(new BaseStructureVerifier<S, E>());
}
@Override
public void verify(StateMachineModel<S, E> model) {
for (Iterator<StateMachineModelVerifier<S, E>> iterator = getItems().reverse(); iterator.hasNext();) {
StateMachineModelVerifier<S, E> verifier = iterator.next();
verifier.verify(model);
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model.verifier;
import org.springframework.statemachine.config.model.StateMachineModel;
/**
* Default implementation of a {@link StateMachineModelVerifier}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class DefaultStateMachineModelVerifier<S, E> implements StateMachineModelVerifier<S, E> {
@Override
public void verify(StateMachineModel<S, E> model) {
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config.model.verifier;
import org.springframework.statemachine.config.model.StateMachineModel;
/**
* Strategy interface for implementations verifying {@link StateMachineModel} structures.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineModelVerifier<S, E> {
/**
* Verify a state machine model.
*
* @param model the state machine model
*/
void verify(StateMachineModel<S, E> model);
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.support;
import java.util.List;
/**
* Base implementation for all composite items.
*
* @author Janne Valkealahti
*
* @param <T> the type of the item
*/
public class AbstractCompositeItems<T> {
/** List of ordered composite items */
private OrderedCompositeItem<T> items;
/**
* Constructs instance with an empty item list.
*/
public AbstractCompositeItems() {
items = new OrderedCompositeItem<T>();
}
/**
* Sets the list of items. This clears
* all existing items.
*
* @param items the new items
*/
public void setItems(List<? extends T> items) {
this.items.setItems(items);
}
/**
* Register a new item.
*
* @param item the item
*/
public void register(T item) {
items.add(item);
}
/**
* Unregister a item.
*
* @param item the item
*/
public void unregister(T item) {
items.remove(item);
}
/**
* Gets the items.
*
* @return the items
*/
public OrderedCompositeItem<T> getItems() {
return items;
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.support;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
/**
* Composite item which can be used in other components which
* may want to allow automatic and annotation based ordering.
* Good use case is a list of listeners where user may want
* to place some of them to be processed before the others.
*
* @author Janne Valkealahti
*
* @param <S> the type of the item
*/
public class OrderedCompositeItem<S> {
private List<S> unordered = new ArrayList<S>();
private List<S> ordered = new ArrayList<S>();
private Comparator<? super S> comparator = new AnnotationAwareOrderComparator();
private List<S> list = new ArrayList<S>();
/**
* Public setter for the listeners.
*
* @param items items
*/
public void setItems(List<? extends S> items) {
unordered.clear();
ordered.clear();
for (S s : items) {
add(s);
}
}
/**
* Register additional item.
*
* @param item item
*/
public void add(S item) {
if (item instanceof Ordered) {
if (!ordered.contains(item)) {
ordered.add(item);
}
} else if (AnnotationUtils.isAnnotationDeclaredLocally(Order.class, item.getClass())) {
if (!ordered.contains(item)) {
ordered.add(item);
}
} else if (!unordered.contains(item)) {
unordered.add(item);
}
Collections.sort(ordered, comparator);
list.clear();
list.addAll(ordered);
list.addAll(unordered);
}
/**
* Unregister item.
*
* @param item item
*/
public void remove(S item) {
ordered.remove(item);
unordered.remove(item);
Collections.sort(ordered, comparator);
list.clear();
list.addAll(ordered);
list.addAll(unordered);
}
/**
* Public getter for the list of items. The {@link Ordered} items come
* first, followed by any unordered ones.
*
* @return an iterator over the list of items
*/
public Iterator<S> iterator() {
return new ArrayList<S>(list).iterator();
}
/**
* Public getter for the list of items in reverse. The {@link Ordered} items
* come last, after any unordered ones.
*
* @return an iterator over the list of items
*/
public Iterator<S> reverse() {
ArrayList<S> result = new ArrayList<S>(list);
Collections.reverse(result);
return result.iterator();
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2016 the original author or authors.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.springframework.statemachine.config;
import static org.hamcrest.Matchers.isA;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.AbstractStateMachineTests;
import org.springframework.statemachine.config.StateMachineBuilder.Builder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.model.MalformedConfigurationException;
public class ConfigurationErrorTests extends AbstractStateMachineTests {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Test
public void testFoo1() {
expectedException.expectCause(isA(MalformedConfigurationException.class));
context.register(Config1.class);
context.refresh();
}
@Test
public void testFoo2() throws Exception {
expectedException.expectCause(isA(MalformedConfigurationException.class));
Builder<String, String> builder = StateMachineBuilder.builder();
builder
.configureStates()
.withStates()
.state("S1")
.state("S2");
builder
.configureTransitions()
.withExternal()
.source("S1")
.target("S2")
.event("E1");
builder.build();
}
@Configuration
@EnableStateMachine
public static class Config1 extends StateMachineConfigurerAdapter<String, String> {
// initial state not set
@Override
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
states
.withStates()
//.initial("S1")
.state("S1")
.state("S2");
}
@Override
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
transitions
.withExternal()
.source("S1")
.target("S2")
.event("E1");
}
}
}

View File

@@ -33,11 +33,11 @@ import org.springframework.statemachine.StateMachineSystemConstants;
import org.springframework.statemachine.TestUtils;
import org.springframework.statemachine.config.StateMachineBuilder.Builder;
import org.springframework.statemachine.config.builders.StateMachineConfigBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.model.StateMachineConfigurationConfig;
import org.springframework.statemachine.config.model.StateMachineStates;
import org.springframework.statemachine.config.model.StateMachineTransitions;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,8 +29,8 @@ import org.springframework.statemachine.AbstractStateMachineTests.TestEvents;
import org.springframework.statemachine.AbstractStateMachineTests.TestExitAction;
import org.springframework.statemachine.AbstractStateMachineTests.TestStates;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.StateData;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.state.PseudoStateKind;
public class DefaultStateConfigurerTests {