Add base support for eclipse papyrus modeling

- First stage to add support for UI modeling via
  eclipse uml2 and papyrus frameworks.
- Add new interface StateMachineModelFactory which is
  a central point of building machines models outside
  of a normal annotation/build classes. What this mean is
  a hook to config model so that machine can be defined
  via a model factory, instead of writing config based on
  normal adapter callbacks.
- Integrate model config into an annotation model so that
  you can still use normal adapters but point those to
  model factory classes, which then allows external hooks
  for machine configuration.
- New spring-statemachine-uml package which supports
  eclipse uml2/emf frameworks to define a machine config.
- Relates to #193
This commit is contained in:
Janne Valkealahti
2016-04-09 16:04:16 +01:00
parent 6cce27e30b
commit 51145f1368
31 changed files with 1842 additions and 13 deletions

View File

@@ -212,6 +212,43 @@ project('spring-statemachine-cluster') {
}
}
project('spring-statemachine-uml') {
description = "Spring State Machine Uml"
dependencies {
compile project(":spring-statemachine-core")
optional "org.springframework.security:spring-security-core:$springSecurityVersion"
// these eclipse maven deps are simply broken
compile("org.eclipse.uml2:uml:$eclipseUml2UmlVersion") { dep ->
exclude group: "org.eclipse.core", module: "runtime"
exclude group: "org.eclipse.emf", module: "ecore"
exclude group: "org.eclipse.emf.ecore", module: "xmi"
exclude group: "org.eclipse.emf.mapping", module: "ecore2xml"
exclude group: "org.eclipse.uml2", module: "common"
exclude group: "org.eclipse.uml2", module: "types"
}
compile("org.eclipse.uml2:types:$eclipseUml2TypesVersion") { dep ->
exclude group: "org.eclipse.core", module: "runtime"
exclude group: "org.eclipse.emf", module: "ecore"
exclude group: "org.eclipse.uml2", module: "common"
}
compile("org.eclipse.uml2:common:$eclipseUml2CommonVersion") { dep ->
exclude group: "org.eclipse.core", module: "runtime"
exclude group: "org.eclipse.emf", module: "ecore"
}
compile "org.eclipse.emf:org.eclipse.emf.ecore.xmi:$eclipseEmfXmiVersion"
compile "org.eclipse.emf:org.eclipse.emf.ecore:$eclipseEmfEcoreVersion"
compile "org.eclipse.emf:org.eclipse.emf.common:$eclipseEmfCommonVersion"
testCompile "org.springframework:spring-test:$springVersion"
testCompile "org.hamcrest:hamcrest-core:$hamcrestVersion"
testCompile "org.hamcrest:hamcrest-library:$hamcrestVersion"
testCompile "junit:junit:$junitVersion"
testRuntime "log4j:log4j:$log4jVersion"
}
}
configure(recipeProjects()) {
dependencies {
compile project(":spring-statemachine-recipes-common")

View File

@@ -17,4 +17,10 @@ tomcatEmbedVersion=8.0.30
servletApiVersion=3.0.1
commonsPool2Version=2.4.2
hsqlVersion=2.3.1
eclipseUml2UmlVersion=5.0.0-v20140602-0749
eclipseUml2TypesVersion=2.0.0-v20140602-0749
eclipseUml2CommonVersion=2.0.0-v20140602-0749
eclipseEmfXmiVersion=2.11.1-v20150805-0538
eclipseEmfEcoreVersion=2.11.1-v20150805-0538
eclipseEmfCommonVersion=2.11.0-v20150805-0538

View File

@@ -6,6 +6,7 @@ include 'spring-statemachine-kryo'
include 'spring-statemachine-zookeeper'
include 'spring-statemachine-redis'
include 'spring-statemachine-cluster'
include 'spring-statemachine-uml'
include 'spring-statemachine-recipes'

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.
@@ -19,6 +19,8 @@ import org.springframework.statemachine.config.builders.StateMachineConfigBuilde
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineConfigurer;
import org.springframework.statemachine.config.builders.StateMachineModelBuilder;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
@@ -36,12 +38,14 @@ import org.springframework.statemachine.config.common.annotation.ObjectPostProce
*/
public abstract class AbstractStateMachineConfigurerAdapter<S, E> implements StateMachineConfigurer<S, E> {
private StateMachineModelBuilder<S, E> modelBuilder;
private StateMachineTransitionBuilder<S, E> transitionBuilder;
private StateMachineStateBuilder<S, E> stateBuilder;
private StateMachineConfigurationBuilder<S, E> configurationBuilder;
@Override
public final void init(StateMachineConfigBuilder<S, E> config) throws Exception {
config.setSharedObject(StateMachineModelBuilder.class, getStateMachineModelBuilder());
config.setSharedObject(StateMachineTransitionBuilder.class, getStateMachineTransitionBuilder());
config.setSharedObject(StateMachineStateBuilder.class, getStateMachineStateBuilder());
config.setSharedObject(StateMachineConfigurationBuilder.class, getStateMachineConfigurationBuilder());
@@ -51,6 +55,10 @@ public abstract class AbstractStateMachineConfigurerAdapter<S, E> implements Sta
public void configure(StateMachineConfigBuilder<S, E> config) throws Exception {
}
@Override
public void configure(StateMachineModelConfigurer<S, E> model) throws Exception {
}
@Override
public void configure(StateMachineConfigurationConfigurer<S, E> config) throws Exception {
}
@@ -68,6 +76,15 @@ public abstract class AbstractStateMachineConfigurerAdapter<S, E> implements Sta
return builder instanceof StateMachineConfigBuilder;
}
protected final StateMachineModelBuilder<S, E> getStateMachineModelBuilder() throws Exception {
if (modelBuilder != null) {
return modelBuilder;
}
modelBuilder = new StateMachineModelBuilder<S, E>(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR, true);
configure(modelBuilder);
return modelBuilder;
}
protected final StateMachineTransitionBuilder<S, E> getStateMachineTransitionBuilder() throws Exception {
if (transitionBuilder != null) {
return transitionBuilder;

View File

@@ -23,6 +23,8 @@ import org.springframework.statemachine.config.builders.StateMachineConfigBuilde
import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineConfigurer;
import org.springframework.statemachine.config.builders.StateMachineModelBuilder;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
@@ -75,6 +77,15 @@ public class StateMachineBuilder {
builder = new StateMachineConfigBuilder<S, E>();
}
/**
* Configure model.
*
* @return the state machine model configurer
*/
public StateMachineModelConfigurer<S, E> configureModel() {
return adapter.modelBuilder;
}
/**
* Configure configuration.
*
@@ -144,12 +155,14 @@ public class StateMachineBuilder {
private static class BuilderStateMachineConfigurerAdapter<S extends Object, E extends Object>
implements StateMachineConfigurer<S, E> {
private StateMachineModelBuilder<S, E> modelBuilder;
private StateMachineTransitionBuilder<S, E> transitionBuilder;
private StateMachineStateBuilder<S, E> stateBuilder;
private StateMachineConfigurationBuilder<S, E> configurationBuilder;
BuilderStateMachineConfigurerAdapter() {
try {
getStateMachineModelBuilder();
getStateMachineTransitionBuilder();
getStateMachineStateBuilder();
getStateMachineConfigurationBuilder();
@@ -160,6 +173,7 @@ public class StateMachineBuilder {
@Override
public void init(StateMachineConfigBuilder<S, E> config) throws Exception {
config.setSharedObject(StateMachineModelBuilder.class, getStateMachineModelBuilder());
config.setSharedObject(StateMachineTransitionBuilder.class, getStateMachineTransitionBuilder());
config.setSharedObject(StateMachineStateBuilder.class, getStateMachineStateBuilder());
config.setSharedObject(StateMachineConfigurationBuilder.class, getStateMachineConfigurationBuilder());
@@ -174,6 +188,10 @@ public class StateMachineBuilder {
return false;
}
@Override
public void configure(StateMachineModelConfigurer<S, E> model) throws Exception {
}
@Override
public void configure(StateMachineConfigurationConfigurer<S, E> config) throws Exception {
}
@@ -186,6 +204,15 @@ public class StateMachineBuilder {
public void configure(StateMachineTransitionConfigurer<S, E> transitions) throws Exception {
}
protected final StateMachineModelBuilder<S, E> getStateMachineModelBuilder() throws Exception {
if (modelBuilder != null) {
return modelBuilder;
}
modelBuilder = new StateMachineModelBuilder<S, E>(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR, true);
configure(modelBuilder);
return modelBuilder;
}
protected final StateMachineTransitionBuilder<S, E> getStateMachineTransitionBuilder() throws Exception {
if (transitionBuilder != null) {
return transitionBuilder;
@@ -209,7 +236,5 @@ public class StateMachineBuilder {
configurationBuilder = new StateMachineConfigurationBuilder<S, E>(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR, true);
return configurationBuilder;
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.builders;
import org.springframework.statemachine.config.configurers.ModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
/**
* Data object used return and build data from a {@link ModelConfigurer}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class ModelData<S, E> {
private StateMachineModelFactory<S, E> factory;
/**
* Instantiates a new model data.
*
* @param factory the factory
*/
public ModelData(StateMachineModelFactory<S, E> factory) {
this.factory = factory;
}
/**
* Gets the factory.
*
* @return the factory
*/
public StateMachineModelFactory<S, E> getFactory() {
return factory;
}
}

View File

@@ -17,10 +17,21 @@ 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.common.annotation.AnnotationBuilder;
import org.springframework.statemachine.config.model.ConfigurationData;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.config.model.StatesData;
import org.springframework.statemachine.config.model.TransitionsData;
/**
* {@link AnnotationBuilder} handling all shared builders which effectively contructs
* full configuration for {@link StateMachineConfig}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class StateMachineConfigBuilder<S, E>
extends
AbstractConfiguredAnnotationBuilder<StateMachineConfig<S, E>, StateMachineConfigBuilder<S, E>, StateMachineConfigBuilder<S, E>> {
@@ -28,17 +39,30 @@ public class StateMachineConfigBuilder<S, E>
@SuppressWarnings("unchecked")
@Override
protected StateMachineConfig<S, E> performBuild() throws Exception {
// TODO: should prevent calling state/transition builder if model is given
StateMachineModelBuilder<?, ?> modelBuilder = getSharedObject(StateMachineModelBuilder.class);
StateMachineConfigurationBuilder<?, ?> configurationBuilder = getSharedObject(StateMachineConfigurationBuilder.class);
StateMachineTransitionBuilder<?, ?> transitionBuilder = getSharedObject(StateMachineTransitionBuilder.class);
StateMachineStateBuilder<?, ?> stateBuilder = getSharedObject(StateMachineStateBuilder.class);
// build config first as it's shared with transition builder
ConfigurationData<S, E> config = (ConfigurationData<S, E>) configurationBuilder.build();
transitionBuilder.setSharedObject(ConfigurationData.class, config);
TransitionsData<S, E> transitions = (TransitionsData<S, E>) transitionBuilder.build();
StatesData<S, E> states = (StatesData<S, E>) stateBuilder.build();
StateMachineConfig<S, E> bean = new StateMachineConfig<S, E>(config, transitions, states);
return bean;
}
ModelData<S, E> model = (ModelData<S, E>) modelBuilder.build();
ConfigurationData<S, E> stateMachineConfigurationConfig = null;
TransitionsData<S, E> transitions = null;
StatesData<S, E> states = null;
if (model.getFactory() != null) {
StateMachineModel<S,E> stateMachineModel = model.getFactory().build();
transitions = stateMachineModel.getTransitionsData();
states = stateMachineModel.getStatesData();
}
stateMachineConfigurationConfig = (ConfigurationData<S, E>) configurationBuilder.build();
if (transitions == null) {
transitionBuilder.setSharedObject(ConfigurationData.class, stateMachineConfigurationConfig);
transitions = (TransitionsData<S, E>) transitionBuilder.build();
}
if (states == null) {
states = (StatesData<S, E>) stateBuilder.build();
}
return new StateMachineConfig<S, E>(stateMachineConfigurationConfig, transitions, states);
}
}

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,6 +29,14 @@ import org.springframework.statemachine.config.common.annotation.AnnotationConfi
public interface StateMachineConfigurer<S, E> extends
AnnotationConfigurer<StateMachineConfig<S, E>, StateMachineConfigBuilder<S, E>> {
/**
* Callback for {@link StateMachineModelConfigurer}.
*
* @param model the {@link StateMachineModelConfigurer}
* @throws Exception if configuration error happens
*/
void configure(StateMachineModelConfigurer<S, E> model) throws Exception;
/**
* Callback for {@link StateMachineConfigurationConfigurer}.
*
@@ -52,5 +60,4 @@ public interface StateMachineConfigurer<S, E> extends
* @throws Exception if configuration error happens
*/
void configure(StateMachineTransitionConfigurer<S, E> transitions) throws Exception;
}

View File

@@ -0,0 +1,79 @@
/*
* 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.builders;
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.DefaultModelConfigurer;
import org.springframework.statemachine.config.configurers.ModelConfigurer;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
/**
* {@link AnnotationBuilder} for {@link ModelData}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class StateMachineModelBuilder<S, E>
extends AbstractConfiguredAnnotationBuilder<ModelData<S, E>, StateMachineModelConfigurer<S, E>, StateMachineModelBuilder<S, E>>
implements StateMachineModelConfigurer<S, E> {
private StateMachineModelFactory<S, E> factory;
/**
* Instantiates a new state machine model builder.
*/
public StateMachineModelBuilder() {
super();
}
/**
* Instantiates a new state machine model builder.
*
* @param objectPostProcessor the object post processor
* @param allowConfigurersOfSameType the allow configurers of same type
*/
public StateMachineModelBuilder(ObjectPostProcessor<Object> objectPostProcessor,
boolean allowConfigurersOfSameType) {
super(objectPostProcessor, allowConfigurersOfSameType);
}
/**
* Instantiates a new state machine model builder.
*
* @param objectPostProcessor the object post processor
*/
public StateMachineModelBuilder(ObjectPostProcessor<Object> objectPostProcessor) {
super(objectPostProcessor);
}
@Override
protected ModelData<S, E> performBuild() throws Exception {
return new ModelData<S, E>(factory);
}
@Override
public ModelConfigurer<S, E> withModel() throws Exception {
return apply(new DefaultModelConfigurer<S, E>());
}
public void setStateMachineModelFactory(StateMachineModelFactory<S, E> factory) {
this.factory = factory;
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.builders;
import org.springframework.statemachine.config.configurers.ModelConfigurer;
/**
* Configurer interface exposing model.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineModelConfigurer<S, E> {
/**
* Gets a configurer for model.
*
* @return {@link ModelConfigurer} for chaining
* @throws Exception if configuration error happens
*/
ModelConfigurer<S, E> withModel() throws Exception;
}

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.configurers;
import org.springframework.statemachine.config.builders.ModelData;
import org.springframework.statemachine.config.builders.StateMachineModelBuilder;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerAdapter;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
/**
* Default implementation of a {@link ModelConfigurer}.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public class DefaultModelConfigurer<S, E>
extends AnnotationConfigurerAdapter<ModelData<S, E>, StateMachineModelConfigurer<S, E>, StateMachineModelBuilder<S, E>>
implements ModelConfigurer<S, E> {
private StateMachineModelFactory<S, E> factory;
@Override
public void configure(StateMachineModelBuilder<S, E> builder) throws Exception {
builder.setStateMachineModelFactory(factory);
}
@Override
public ModelConfigurer<S, E> factory(StateMachineModelFactory<S, E> factory) {
this.factory = factory;
return this;
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.configurers;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurerBuilder;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
/**
* Base {@code ModelConfigurer} interface for configuring state machine model.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface ModelConfigurer<S, E> extends
AnnotationConfigurerBuilder<StateMachineModelConfigurer<S, E>> {
/**
* Specify a state machine model factory.
*
* @param factory the state machine model factory
* @return configurer for chaining
*/
ModelConfigurer<S, E> factory(StateMachineModelFactory<S, E> factory);
}

View File

@@ -0,0 +1,118 @@
/*
* 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.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
/**
* Base implementation of a {@link StateMachineModelFactory} providing
* some common grounds for various implementations.
*
* This factory is able to resolve {@link Action}s or {@link Guard}s either from
* a {@link BeanFactory} if knows, or from manually registered instances. Manually
* registered actions or guards are needed if those are not created as beans or if
* whole state machine is working outside of an application context.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public abstract class AbstractStateMachineModelFactory<S, E> implements StateMachineComponentResolver<S, E>, BeanFactoryAware {
private BeanFactory beanFactory;
private final Map<String, Action<S, E>> registeredActions = new HashMap<>();
private final Map<String, Guard<S, E>> registeredGuards = new HashMap<>();
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
/**
* Register {@link Action} into factory with a given id.
*
* @param id the id
* @param action the action
*/
public void registerAction(String id, Action<S, E> action) {
registeredActions.put(id, action);
}
/**
* Register {@link Guard} into factory with a given id.
*
* @param id the id
* @param guard the guard
*/
public void registerGuard(String id, Guard<S, E> guard) {
registeredGuards.put(id, guard);
}
/**
* Gets the bean factory.
*
* @return the bean factory
*/
protected final BeanFactory getBeanFactory() {
return beanFactory;
}
/**
* Resolve action.
*
* @param id the id
* @return the action
*/
@SuppressWarnings("unchecked")
public Action<S, E> resolveAction(String id) {
Action<S, E> a = null;
a = registeredActions.get(id);
if (a == null && beanFactory != null) {
a = beanFactory.getBean(id, Action.class);
}
if (a == null) {
throw new RuntimeException("Can't resolve action with id " + id + " either from registered actions nor beanfactory");
}
return a;
}
/**
* Resolve guard.
*
* @param id the id
* @return the guard
*/
@SuppressWarnings("unchecked")
public Guard<S, E> resolveGuard(String id) {
Guard<S, E> g = null;
g = registeredGuards.get(id);
if (g == null && beanFactory != null) {
g = beanFactory.getBean(id, Guard.class);
}
if (g == null) {
throw new RuntimeException("Can't resolve guard with id " + id + " either from registered guards nor beanfactory");
}
return g;
}
}

View File

@@ -64,6 +64,18 @@ public class StateData<S, E> {
this(null, null, state, null, null, null, initial);
}
/**
* Instantiates a new state data.
*
* @param parent the parent
* @param region the region
* @param state the state
* @param initial the initial
*/
public StateData(Object parent, Object region, S state, boolean initial) {
this(parent, region, state, null, null, null, initial);
}
/**
* Instantiates a new state data.
*

View File

@@ -0,0 +1,63 @@
/*
* 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 org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
/**
* Strategy interface for registering and resolving state machine
* components by their id's
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineComponentResolver<S, E> {
/**
* Register {@link Action} into factory with a given id.
*
* @param id the id
* @param action the action
*/
void registerAction(String id, Action<S, E> action);
/**
* Register {@link Guard} into factory with a given id.
*
* @param id the id
* @param guard the guard
*/
void registerGuard(String id, Guard<S, E> guard);
/**
* Resolve action.
*
* @param id the id
* @return the action
*/
Action<S, E> resolveAction(String id);
/**
* Resolve guard.
*
* @param id the id
* @return the guard
*/
Guard<S, E> resolveGuard(String id);
}

View File

@@ -0,0 +1,34 @@
/*
* 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;
/**
* A generic builder interface for building {@link StateMachineModel}s.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineModelFactory<S, E> {
/**
* Builds the state machine model.
*
* @return the state machine model
*/
StateMachineModel<S, E> build();
}

View File

@@ -0,0 +1,145 @@
/*
* 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 static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.AbstractStateMachineTests;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.ObjectStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
public class StateMachineModelFactoryTests extends AbstractStateMachineTests {
@Test
public void testResolvingFromContext() {
context.register(Config1.class);
context.refresh();
TestStateMachineModelFactory modelBuilder = new TestStateMachineModelFactory();
modelBuilder.setBeanFactory(context);
ObjectStateMachineFactory<String, String> factory = new ObjectStateMachineFactory<>(modelBuilder.build());
StateMachine<String,String> stateMachine = factory.getStateMachine();
stateMachine.start();
assertThat(stateMachine.getState().getIds(), contains("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), contains("S2"));
}
@Test
public void testFromAnnotationConfig() {
context.register(Config2.class);
context.refresh();
@SuppressWarnings("unchecked")
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), contains("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), contains("S2"));
}
@Configuration
static class Config1 {
@Bean
public Action<String, String> action1() {
return new Action<String, String>() {
@Override
public void execute(StateContext<String, String> context) {
}
};
}
}
@Configuration
@EnableStateMachine
public static class Config2 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new TestStateMachineModelFactory();
}
@Bean
public Action<String, String> action1() {
return new Action<String, String>() {
@Override
public void execute(StateContext<String, String> context) {
}
};
}
}
@SuppressWarnings("unchecked")
private static class TestStateMachineModelFactory implements StateMachineModelFactory<String, String>, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public StateMachineModel<String, String> build() {
Action<String, String> action1 = beanFactory.getBean("action1", Action.class);
Collection<Action<String, String>> s2Actions = new ArrayList<>();
s2Actions.add(action1);
ConfigurationData<String, String> configurationData = new ConfigurationData<>();
Collection<StateData<String, String>> stateData = new ArrayList<>();
stateData.add(new StateData<String, String>("S1", true));
stateData.add(new StateData<String, String>(null, null, "S2", null, s2Actions, null));
StatesData<String, String> statesData = new StatesData<>(stateData);
Collection<TransitionData<String, String>> transitionData = new ArrayList<>();
transitionData.add(new TransitionData<String, String>("S1", "S2", "E1"));
TransitionsData<String, String> transitionsData = new TransitionsData<>(transitionData);
StateMachineModel<String, String> stateMachineModel = new DefaultStateMachineModel<>(configurationData, statesData, transitionsData);
return stateMachineModel;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
}

View File

@@ -0,0 +1,183 @@
/*
* 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.uml;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.Event;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Region;
import org.eclipse.uml2.uml.Signal;
import org.eclipse.uml2.uml.SignalEvent;
import org.eclipse.uml2.uml.State;
import org.eclipse.uml2.uml.StateMachine;
import org.eclipse.uml2.uml.Transition;
import org.eclipse.uml2.uml.Trigger;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.Vertex;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineComponentResolver;
import org.springframework.statemachine.config.model.StatesData;
import org.springframework.statemachine.config.model.TransitionData;
import org.springframework.statemachine.config.model.TransitionsData;
import org.springframework.util.Assert;
/**
* Model parser which constructs states and transitions data out from
* an uml model.
*
* @author Janne Valkealahti
*/
public class UmlModelParser {
private final Model model;
private final StateMachineComponentResolver<String, String> resolver;
private final Collection<StateData<String, String>> stateDatas = new ArrayList<StateData<String, String>>();
private final Collection<TransitionData<String, String>> transitionDatas = new ArrayList<TransitionData<String, String>>();
/**
* Instantiates a new uml model parser.
*
* @param model the model
* @param resolver the resolver
*/
public UmlModelParser(Model model, StateMachineComponentResolver<String, String> resolver) {
Assert.notNull(model, "Model must be set");
Assert.notNull(resolver, "Resolver must be set");
this.model = model;
this.resolver = resolver;
}
/**
* Parses the model.
*
* @return the data holder for states and transitions
*/
public DataHolder parseModel() {
EList<PackageableElement> packagedElements = model.getPackagedElements();
// expect model having exactly one machine
StateMachine stateMachine = (StateMachine) EcoreUtil.getObjectByType(packagedElements, UMLPackage.Literals.STATE_MACHINE);
if (stateMachine == null) {
throw new IllegalArgumentException("Can't find statemachine from model");
}
for (Region region : stateMachine.getRegions()) {
handleRegion(region);
}
return new DataHolder(new StatesData<>(stateDatas), new TransitionsData<String, String>(transitionDatas));
}
private void handleRegion(Region region) {
// build states
for (Vertex vertex : region.getSubvertices()) {
if (vertex instanceof State) {
State state = (State)vertex;
// find parent state if submachine state, root states have null parent
String parent = null;
if (state.getContainer().getOwner() instanceof State) {
parent = ((State)state.getContainer().getOwner()).getName();
}
StateData<String, String> stateData = handleActions(
new StateData<String, String>(parent, null, state.getName(), UmlUtils.isInitialState(state)), state);
stateDatas.add(stateData);
// do recursive handling of regions
for (Region sub : state.getRegions()) {
handleRegion(sub);
}
}
}
// build transitions
for (Transition transition : region.getTransitions()) {
for (Trigger trigger : transition.getTriggers()) {
Event event = trigger.getEvent();
if (event instanceof SignalEvent) {
Signal signal = ((SignalEvent)event).getSignal();
if (signal != null) {
transitionDatas.add(new TransitionData<String, String>(transition.getSource().getName(),
transition.getTarget().getName(), signal.getName()));
}
}
}
}
}
private StateData<String, String> handleActions(StateData<String, String> stateData, State state) {
if (state.getEntry() instanceof Activity) {
String beanId = ((Activity)state.getEntry()).getName();
Action<String, String> bean = resolver.resolveAction(beanId);
if (bean != null) {
ArrayList<Action<String, String>> entrys = new ArrayList<Action<String, String>>();
entrys.add(bean);
stateData.setEntryActions(entrys);
}
}
if (state.getExit() instanceof Activity) {
String beanId = ((Activity)state.getExit()).getName();
Action<String, String> bean = resolver.resolveAction(beanId);
if (bean != null) {
ArrayList<Action<String, String>> exits = new ArrayList<Action<String, String>>();
exits.add(bean);
stateData.setExitActions(exits);
}
}
return stateData;
}
/**
* Holder object for results returned from uml parser.
*/
protected class DataHolder {
private final StatesData<String, String> statesData;
private final TransitionsData<String, String> transitionsData;
/**
* Instantiates a new data holder.
*
* @param statesData the states data
* @param transitionsData the transitions data
*/
public DataHolder(StatesData<String, String> statesData, TransitionsData<String, String> transitionsData) {
this.statesData = statesData;
this.transitionsData = transitionsData;
}
/**
* Gets the states data.
*
* @return the states data
*/
public StatesData<String, String> getStatesData() {
return statesData;
}
/**
* Gets the transitions data.
*
* @return the transitions data
*/
public TransitionsData<String, String> getTransitionsData() {
return transitionsData;
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.uml;
import java.io.IOException;
import org.eclipse.uml2.uml.Model;
import org.springframework.core.io.Resource;
import org.springframework.statemachine.config.model.AbstractStateMachineModelFactory;
import org.springframework.statemachine.config.model.ConfigurationData;
import org.springframework.statemachine.config.model.DefaultStateMachineModel;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.uml.UmlModelParser.DataHolder;
import org.springframework.util.Assert;
/**
* {@link StateMachineModelFactory} which builds {@link StateMachineModel} from
* uml representation.
*
* @author Janne Valkealahti
*/
public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactory<String, String>
implements StateMachineModelFactory<String, String> {
private final Resource resource;
/**
* Instantiates a new uml state machine model factory.
*
* @param resource the resource
*/
public UmlStateMachineModelFactory(Resource resource) {
Assert.notNull(resource, "Resource must be set");
this.resource = resource;
}
@Override
public StateMachineModel<String, String> build() {
Model model = null;
try {
model = UmlUtils.getModel(resource.getURI().getPath());
} catch (IOException e) {
throw new IllegalArgumentException("Cannot build build model from resource " + resource, e);
}
UmlModelParser parser = new UmlModelParser(model, this);
DataHolder dataHolder = parser.parseModel();
ConfigurationData<String, String> configurationData = new ConfigurationData<>();
return new DefaultStateMachineModel<String, String>(configurationData, dataHolder.getStatesData(), dataHolder.getTransitionsData());
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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.uml;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Pseudostate;
import org.eclipse.uml2.uml.PseudostateKind;
import org.eclipse.uml2.uml.State;
import org.eclipse.uml2.uml.Transition;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
/**
* Utilities for uml model processing.
*
* @author Janne Valkealahti
*/
public abstract class UmlUtils {
/**
* Gets the model.
*
* @param modelPath the model path
* @return the model
*/
public static Model getModel(String modelPath) {
URI modelUri = URI.createFileURI(modelPath);
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
resourceSet.createResource(modelUri);
Resource resource = resourceSet.getResource(modelUri, true);
Model m = (Model) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.Literals.MODEL);
return m;
}
/**
* Checks if {@link State} is an initial state by checking if
* it has incoming transition from UML's initial literal.
*
* @param state the state
* @return true, if is initial state
*/
public static boolean isInitialState(State state) {
for (Transition t : state.getIncomings()) {
if (t.getSource() instanceof Pseudostate) {
if (((Pseudostate)t.getSource()).getKind() == PseudostateKind.INITIAL_LITERAL) {
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,43 @@
/*
* 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.uml;
import org.junit.After;
import org.junit.Before;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public abstract class AbstractUmlTests {
protected AnnotationConfigApplicationContext context;
@Before
public void setup() {
context = buildContext();
}
@After
public void clean() {
if (context != null) {
context.close();
}
context = null;
}
protected AnnotationConfigApplicationContext buildContext() {
return null;
}
}

View File

@@ -0,0 +1,187 @@
/*
* 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.uml;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
public class UmlStateMachineModelFactoryTests extends AbstractUmlTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Test
public void testSimpleFlat() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-flat.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.registerAction("action1", new LatchAction());
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(2));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleSubmachine() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-submachine.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(4));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getParent(), nullValue());
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getParent(), nullValue());
} else if (stateData.getState().equals("S11")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getParent(), is("S1"));
} else if (stateData.getState().equals("S12")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getParent(), is("S1"));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleFlatMachine() throws Exception {
context.register(Config2.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction action1 = context.getBean("action1", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), contains("S1"));
stateMachine.sendEvent("E1");
assertThat(action1.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(stateMachine.getState().getIds(), contains("S2"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleSubmachineMachine() throws Exception {
context.register(Config3.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), contains("S1", "S11"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), contains("S1", "S12"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), contains("S2"));
}
@Configuration
@EnableStateMachine
public static class Config2 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-flat.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public Action<String, String> action1() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config3 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-submachine.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public Action<String, String> action1() {
return new LatchAction();
}
}
public static class LatchAction implements Action<String, String> {
CountDownLatch latch = new CountDownLatch(1);
@Override
public void execute(StateContext<String, String> context) {
latch.countDown();
}
}
}

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_f2rgYPzhEeWmAaqzrMaEkA" type="PapyrusUMLStateMachineDiagram" name="StateMachine Diagram" measurementUnit="Pixel">
<children xmi:type="notation:Shape" xmi:id="_f2rgYfzhEeWmAaqzrMaEkA" type="2000">
<children xmi:type="notation:DecorationNode" xmi:id="_f2rgYvzhEeWmAaqzrMaEkA" type="2001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_f2rgY_zhEeWmAaqzrMaEkA" width="700" height="23"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_f2rgZPzhEeWmAaqzrMaEkA" type="2002">
<children xmi:type="notation:Shape" xmi:id="_f2rgZfzhEeWmAaqzrMaEkA" type="3000">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_f2rgZvzhEeWmAaqzrMaEkA" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_f2rgZ_zhEeWmAaqzrMaEkA" key="RegionZoneKey" value=""/>
</eAnnotations>
<children xmi:type="notation:DecorationNode" xmi:id="_f2rgaPzhEeWmAaqzrMaEkA" type="3002">
<children xmi:type="notation:Shape" xmi:id="_gpYIoPzhEeWmAaqzrMaEkA" type="8000">
<children xmi:type="notation:DecorationNode" xmi:id="_gpYIovzhEeWmAaqzrMaEkA" type="8001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_gpYvsPzhEeWmAaqzrMaEkA" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_gpYvsfzhEeWmAaqzrMaEkA" type="8002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_gpYvsvzhEeWmAaqzrMaEkA" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="simple-flat.uml#_gpQM0PzhEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_gpYIofzhEeWmAaqzrMaEkA" x="41" y="85"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_hHTawPzhEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_hHTawvzhEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_jOdi0P1VEeWmAaqzrMaEkA" width="113"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_hHTaw_zhEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_hHTaxPzhEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_hHTaxfzhEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_hHTaxvzhEeWmAaqzrMaEkA" y="-1" width="113"/>
</children>
<element xmi:type="uml:State" href="simple-flat.uml#_hHMGAPzhEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_hHTawfzhEeWmAaqzrMaEkA" x="203" y="63" width="113" height="65"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_hsdWQPzhEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_hsd9UPzhEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_isZXkP1VEeWmAaqzrMaEkA" width="182"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_hsd9UfzhEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_hsd9UvzhEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_hsd9U_zhEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_hsd9VPzhEeWmAaqzrMaEkA" y="-1" width="182"/>
</children>
<children xmi:type="notation:BasicCompartment" xmi:id="_W_XlMP1UEeWmAaqzrMaEkA" type="compartment_shape_display">
<styles xmi:type="notation:TitleStyle" xmi:id="_W_XlMf1UEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_W_XlMv1UEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_lrty8P1WEeWmAaqzrMaEkA" type="690">
<element xmi:type="uml:Activity" href="simple-flat.uml#_lrP44P1WEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Location" xmi:id="_lrty8f1WEeWmAaqzrMaEkA"/>
</children>
<element xmi:type="uml:State" href="simple-flat.uml#_hsWBgPzhEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_hsdWQfzhEeWmAaqzrMaEkA" x="468" y="65" width="182"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_f2rgafzhEeWmAaqzrMaEkA"/>
</children>
<element xmi:type="uml:Region" href="simple-flat.uml#_f2qSQPzhEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_f2rgavzhEeWmAaqzrMaEkA" width="700" height="186"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_f2rga_zhEeWmAaqzrMaEkA" y="23" width="700" height="186"/>
</children>
<element xmi:type="uml:StateMachine" href="simple-flat.uml#_f2prMPzhEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_f2rgbPzhEeWmAaqzrMaEkA" x="30" y="30" width="700" height="209"/>
</children>
<styles xmi:type="notation:StringValueStyle" xmi:id="_f2rgbfzhEeWmAaqzrMaEkA" name="diagram_compatibility_version" stringValue="1.1.0"/>
<styles xmi:type="notation:DiagramStyle" xmi:id="_f2rgbvzhEeWmAaqzrMaEkA"/>
<styles xmi:type="style:PapyrusViewStyle" xmi:id="_f2rgb_zhEeWmAaqzrMaEkA">
<owner xmi:type="uml:Model" href="simple-flat.uml#_f2mn4PzhEeWmAaqzrMaEkA"/>
</styles>
<element xmi:type="uml:StateMachine" href="simple-flat.uml#_f2prMPzhEeWmAaqzrMaEkA"/>
<edges xmi:type="notation:Connector" xmi:id="_rrX2cPzhEeWmAaqzrMaEkA" type="7000" source="_gpYIoPzhEeWmAaqzrMaEkA" target="_hHTawPzhEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_rrYdgPzhEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_rrYdgfzhEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_rrYdgvzhEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_rrYdg_zhEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_rrYdhPzhEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_rrYdhfzhEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_rrX2cfzhEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-flat.uml#_roTUUPzhEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_rrX2cvzhEeWmAaqzrMaEkA" points="[4, -8, -161, 0]$[160, -10, -5, -2]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_rsPZIPzhEeWmAaqzrMaEkA" id="(1.0,0.45)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_rsPZIfzhEeWmAaqzrMaEkA" id="(0.0,0.48936170212765956)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_sZaBIPzhEeWmAaqzrMaEkA" type="7000" source="_hHTawPzhEeWmAaqzrMaEkA" target="_hsdWQPzhEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_sZaoMPzhEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_sZaoMfzhEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_sZaoMvzhEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_sZaoM_zhEeWmAaqzrMaEkA" x="-6" y="-20"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_sZaoNPzhEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_sZaoNfzhEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_sZaBIfzhEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-flat.uml#_sZQQIPzhEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_sZaBIvzhEeWmAaqzrMaEkA" points="[40, 9, -159, -40]$[191, 49, -8, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_sZ2GAPzhEeWmAaqzrMaEkA" id="(1.0,0.48936170212765956)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_sZ2GAfzhEeWmAaqzrMaEkA" id="(0.0,0.46808510638297873)"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_f2mn4PzhEeWmAaqzrMaEkA" name="RootElement">
<packagedElement xmi:type="uml:StateMachine" xmi:id="_f2prMPzhEeWmAaqzrMaEkA" name="StateMachine">
<region xmi:type="uml:Region" xmi:id="_f2qSQPzhEeWmAaqzrMaEkA" name="Region1">
<transition xmi:type="uml:Transition" xmi:id="_roTUUPzhEeWmAaqzrMaEkA" source="_gpQM0PzhEeWmAaqzrMaEkA" target="_hHMGAPzhEeWmAaqzrMaEkA"/>
<transition xmi:type="uml:Transition" xmi:id="_sZQQIPzhEeWmAaqzrMaEkA" source="_hHMGAPzhEeWmAaqzrMaEkA" target="_hsWBgPzhEeWmAaqzrMaEkA">
<trigger xmi:type="uml:Trigger" xmi:id="_utY18PzhEeWmAaqzrMaEkA" event="_pFGXwPzhEeWmAaqzrMaEkA"/>
</transition>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_gpQM0PzhEeWmAaqzrMaEkA"/>
<subvertex xmi:type="uml:State" xmi:id="_hHMGAPzhEeWmAaqzrMaEkA" name="S1"/>
<subvertex xmi:type="uml:State" xmi:id="_hsWBgPzhEeWmAaqzrMaEkA" name="S2">
<entry xmi:type="uml:Activity" xmi:id="_lrP44P1WEeWmAaqzrMaEkA" name="action1"/>
</subvertex>
</region>
</packagedElement>
<packagedElement xmi:type="uml:Signal" xmi:id="_moBRUPzhEeWmAaqzrMaEkA" name="E1"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_pFGXwPzhEeWmAaqzrMaEkA" name="SignalEvent1" signal="_moBRUPzhEeWmAaqzrMaEkA"/>
</uml:Model>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_0CHlQP2tEeWmAaqzrMaEkA" type="PapyrusUMLStateMachineDiagram" name="StateMachine Diagram" measurementUnit="Pixel">
<children xmi:type="notation:Shape" xmi:id="_0CHlQf2tEeWmAaqzrMaEkA" type="2000">
<children xmi:type="notation:DecorationNode" xmi:id="_0CHlQv2tEeWmAaqzrMaEkA" type="2001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_0CHlQ_2tEeWmAaqzrMaEkA" width="544" height="23"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_0CHlRP2tEeWmAaqzrMaEkA" type="2002">
<children xmi:type="notation:Shape" xmi:id="_0CHlRf2tEeWmAaqzrMaEkA" type="3000">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_0CHlRv2tEeWmAaqzrMaEkA" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_0CHlR_2tEeWmAaqzrMaEkA" key="RegionZoneKey" value="B"/>
</eAnnotations>
<children xmi:type="notation:DecorationNode" xmi:id="_0CHlSP2tEeWmAaqzrMaEkA" type="3002">
<children xmi:type="notation:Shape" xmi:id="_3k2FIP2tEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_3k2FIv2tEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Uwv9YP5YEeWp9PUPGFd3ig" width="60"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_3k2FI_2tEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_3k2FJP2tEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_3k2FJf2tEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3k2FJv2tEeWmAaqzrMaEkA" y="-1" width="60"/>
</children>
<element xmi:type="uml:State" href="simple-root-regions.uml#_3kyawP2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3k2FIf2tEeWmAaqzrMaEkA" x="190" y="30" width="60"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_3-WKQP2tEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_3-WKQv2tEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_VQAFMP5YEeWp9PUPGFd3ig" width="60"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_3-WKQ_2tEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_3-WKRP2tEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_3-WKRf2tEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3-WKRv2tEeWmAaqzrMaEkA" y="-1" width="60"/>
</children>
<element xmi:type="uml:State" href="simple-root-regions.uml#_3-R40P2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3-WKQf2tEeWmAaqzrMaEkA" x="410" y="30" width="60"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_5AT9kP2tEeWmAaqzrMaEkA" type="8000">
<children xmi:type="notation:DecorationNode" xmi:id="_5AT9kv2tEeWmAaqzrMaEkA" type="8001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_5AT9k_2tEeWmAaqzrMaEkA" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_5AT9lP2tEeWmAaqzrMaEkA" type="8002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_5AT9lf2tEeWmAaqzrMaEkA" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="simple-root-regions.uml#_5ANP4P2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_5AT9kf2tEeWmAaqzrMaEkA" x="70" y="50"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_0CHlSf2tEeWmAaqzrMaEkA"/>
</children>
<element xmi:type="uml:Region" href="simple-root-regions.uml#_0CG-MP2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_0CHlSv2tEeWmAaqzrMaEkA" y="117" width="544" height="136"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_1vBL8f2tEeWmAaqzrMaEkA" type="3000">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_1vBzAv2tEeWmAaqzrMaEkA" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_1vBzA_2tEeWmAaqzrMaEkA" key="RegionZoneKey" value="T"/>
</eAnnotations>
<children xmi:type="notation:DecorationNode" xmi:id="_1vBzAP2tEeWmAaqzrMaEkA" type="3002">
<children xmi:type="notation:Shape" xmi:id="_2uWiAP2tEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_2uXJEP2tEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_TvIIUP5YEeWp9PUPGFd3ig" width="60"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_2uXJEf2tEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_2uXJEv2tEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_2uXJE_2tEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2uXJFP2tEeWmAaqzrMaEkA" y="-1" width="60"/>
</children>
<element xmi:type="uml:State" href="simple-root-regions.uml#_2uUs0P2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2uWiAf2tEeWmAaqzrMaEkA" x="190" y="27" width="60"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_3McMMP2tEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_3McMMv2tEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_UPYVsP5YEeWp9PUPGFd3ig" width="60"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_3McMM_2tEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_3McMNP2tEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_3McMNf2tEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3McMNv2tEeWmAaqzrMaEkA" y="-1" width="60"/>
</children>
<element xmi:type="uml:State" href="simple-root-regions.uml#_3MZI4P2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3McMMf2tEeWmAaqzrMaEkA" x="410" y="27" width="60"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_4YRtMP2tEeWmAaqzrMaEkA" type="8000">
<children xmi:type="notation:DecorationNode" xmi:id="_4YRtMv2tEeWmAaqzrMaEkA" type="8001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_4YRtM_2tEeWmAaqzrMaEkA" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_4YRtNP2tEeWmAaqzrMaEkA" type="8002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_4YRtNf2tEeWmAaqzrMaEkA" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="simple-root-regions.uml#_4YMNoP2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_4YRtMf2tEeWmAaqzrMaEkA" x="70" y="47"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_1vBzAf2tEeWmAaqzrMaEkA"/>
</children>
<element xmi:type="uml:Region" href="simple-root-regions.uml#_1vBL8P2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_1vBL8v2tEeWmAaqzrMaEkA" width="544" height="117"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_0CHlS_2tEeWmAaqzrMaEkA" y="23" width="544" height="254"/>
</children>
<element xmi:type="uml:StateMachine" href="simple-root-regions.uml#_0CFwEP2tEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_0CHlTP2tEeWmAaqzrMaEkA" x="30" y="30" width="544" height="277"/>
</children>
<styles xmi:type="notation:StringValueStyle" xmi:id="_0CHlTf2tEeWmAaqzrMaEkA" name="diagram_compatibility_version" stringValue="1.1.0"/>
<styles xmi:type="notation:DiagramStyle" xmi:id="_0CHlTv2tEeWmAaqzrMaEkA"/>
<styles xmi:type="style:PapyrusViewStyle" xmi:id="_0CHlT_2tEeWmAaqzrMaEkA">
<owner xmi:type="uml:Model" href="simple-root-regions.uml#_0CCswP2tEeWmAaqzrMaEkA"/>
</styles>
<element xmi:type="uml:StateMachine" href="simple-root-regions.uml#_0CFwEP2tEeWmAaqzrMaEkA"/>
<edges xmi:type="notation:Connector" xmi:id="_5uWvUP2tEeWmAaqzrMaEkA" type="7000" source="_4YRtMP2tEeWmAaqzrMaEkA" target="_2uWiAP2tEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_5uXWYP2tEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_5uXWYf2tEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_5uXWYv2tEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_5uXWY_2tEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_5uXWZP2tEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_5uXWZf2tEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_5uWvUf2tEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-root-regions.uml#_5uOMcP2tEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_5uWvUv2tEeWmAaqzrMaEkA" points="[8, 0, -123, 14]$[152, 33, 21, 47]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5uvw4P2tEeWmAaqzrMaEkA" id="(1.0,0.5)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5uvw4f2tEeWmAaqzrMaEkA" id="(0.0,0.5531914893617021)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_6Pj-8P2tEeWmAaqzrMaEkA" type="7000" source="_2uWiAP2tEeWmAaqzrMaEkA" target="_3McMMP2tEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_6PkmAP2tEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_6PkmAf2tEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_6PkmAv2tEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_6PkmA_2tEeWmAaqzrMaEkA" x="7" y="-25"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_6PkmBP2tEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_6PkmBf2tEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_6Pj-8f2tEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-root-regions.uml#_6PbcEP2tEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_6Pj-8v2tEeWmAaqzrMaEkA" points="[51, 6, -178, -1]$[280, 45, 51, 38]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_6P5WIP2tEeWmAaqzrMaEkA" id="(1.0,0.425531914893617)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_6P5WIf2tEeWmAaqzrMaEkA" id="(0.0,0.46200607902735563)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_62654P2tEeWmAaqzrMaEkA" type="7000" source="_5AT9kP2tEeWmAaqzrMaEkA" target="_3k2FIP2tEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_62654_2tEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_62655P2tEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_627g8P2tEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_627g8f2tEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_627g8v2tEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_627g8_2tEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_62654f2tEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-root-regions.uml#_620MMP2tEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_62654v2tEeWmAaqzrMaEkA" points="[5, 7, -129, 23]$[136, -13, 2, 3]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_63PqAP2tEeWmAaqzrMaEkA" id="(1.0,0.4)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_63PqAf2tEeWmAaqzrMaEkA" id="(0.0,0.5531914893617021)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_7ynGEP2tEeWmAaqzrMaEkA" type="7000" source="_3k2FIP2tEeWmAaqzrMaEkA" target="_3-WKQP2tEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_7ynGE_2tEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_7ynGFP2tEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_7ynGFf2tEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_7ynGFv2tEeWmAaqzrMaEkA" x="-11" y="-22"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_7ynGF_2tEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_7ynGGP2tEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_7ynGEf2tEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-root-regions.uml#_7yejMP2tEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_7ynGEv2tEeWmAaqzrMaEkA" points="[51, 8, -163, 2]$[242, 53, 28, 47]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_7y-5gP2tEeWmAaqzrMaEkA" id="(1.0,0.48632218844984804)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_7y-5gf2tEeWmAaqzrMaEkA" id="(0.0,0.48632218844984804)"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_0CCswP2tEeWmAaqzrMaEkA" name="RootElement">
<packagedElement xmi:type="uml:StateMachine" xmi:id="_0CFwEP2tEeWmAaqzrMaEkA" name="StateMachine">
<region xmi:type="uml:Region" xmi:id="_0CG-MP2tEeWmAaqzrMaEkA" name="Region1">
<transition xmi:type="uml:Transition" xmi:id="_620MMP2tEeWmAaqzrMaEkA" source="_5ANP4P2tEeWmAaqzrMaEkA" target="_3kyawP2tEeWmAaqzrMaEkA"/>
<transition xmi:type="uml:Transition" xmi:id="_7yejMP2tEeWmAaqzrMaEkA" source="_3kyawP2tEeWmAaqzrMaEkA" target="_3-R40P2tEeWmAaqzrMaEkA">
<trigger xmi:type="uml:Trigger" xmi:id="_5ouzAP2uEeW4xs9STwG2fA" event="_MGdIAP2uEeWmAaqzrMaEkA"/>
</transition>
<subvertex xmi:type="uml:State" xmi:id="_3kyawP2tEeWmAaqzrMaEkA" name="S3"/>
<subvertex xmi:type="uml:State" xmi:id="_3-R40P2tEeWmAaqzrMaEkA" name="S4"/>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_5ANP4P2tEeWmAaqzrMaEkA"/>
</region>
<region xmi:type="uml:Region" xmi:id="_1vBL8P2tEeWmAaqzrMaEkA" name="Region2">
<transition xmi:type="uml:Transition" xmi:id="_5uOMcP2tEeWmAaqzrMaEkA" source="_4YMNoP2tEeWmAaqzrMaEkA" target="_2uUs0P2tEeWmAaqzrMaEkA"/>
<transition xmi:type="uml:Transition" xmi:id="_6PbcEP2tEeWmAaqzrMaEkA" source="_2uUs0P2tEeWmAaqzrMaEkA" target="_3MZI4P2tEeWmAaqzrMaEkA">
<trigger xmi:type="uml:Trigger" xmi:id="_1_olYP2uEeW4xs9STwG2fA" event="_JRhiQP2uEeWmAaqzrMaEkA"/>
</transition>
<subvertex xmi:type="uml:State" xmi:id="_2uUs0P2tEeWmAaqzrMaEkA" name="S1"/>
<subvertex xmi:type="uml:State" xmi:id="_3MZI4P2tEeWmAaqzrMaEkA" name="S2"/>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_4YMNoP2tEeWmAaqzrMaEkA"/>
</region>
</packagedElement>
<packagedElement xmi:type="uml:Signal" xmi:id="_F2840P2uEeWmAaqzrMaEkA" name="E1"/>
<packagedElement xmi:type="uml:Signal" xmi:id="_HtSvYP2uEeWmAaqzrMaEkA" name="E2"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_JRhiQP2uEeWmAaqzrMaEkA" name="SignalEventE1" signal="_F2840P2uEeWmAaqzrMaEkA"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_MGdIAP2uEeWmAaqzrMaEkA" name="SignalEventE2" signal="_HtSvYP2uEeWmAaqzrMaEkA"/>
</uml:Model>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>

View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_AWUUIfzlEeWmAaqzrMaEkA" type="PapyrusUMLStateMachineDiagram" name="StateMachine Diagram" measurementUnit="Pixel">
<children xmi:type="notation:Shape" xmi:id="_AWUUIvzlEeWmAaqzrMaEkA" type="2000">
<children xmi:type="notation:DecorationNode" xmi:id="_AWUUI_zlEeWmAaqzrMaEkA" type="2001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_AWUUJPzlEeWmAaqzrMaEkA" width="700" height="23"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_AWUUJfzlEeWmAaqzrMaEkA" type="2002">
<children xmi:type="notation:Shape" xmi:id="_AWUUJvzlEeWmAaqzrMaEkA" type="3000">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_AWUUJ_zlEeWmAaqzrMaEkA" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_AWUUKPzlEeWmAaqzrMaEkA" key="RegionZoneKey" value=""/>
</eAnnotations>
<children xmi:type="notation:DecorationNode" xmi:id="_AWUUKfzlEeWmAaqzrMaEkA" type="3002">
<children xmi:type="notation:Shape" xmi:id="_EzEzUPzlEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_EzEzUvzlEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Fm6rEPzlEeWmAaqzrMaEkA" width="421" height="23"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_EzEzU_zlEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_EzEzVPzlEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_EzEzVfzlEeWmAaqzrMaEkA" type="6002">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_L4bscPzlEeWmAaqzrMaEkA" source="PapyrusCSSForceValue">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_L4cTgPzlEeWmAaqzrMaEkA" key="visible" value="true"/>
</eAnnotations>
<children xmi:type="notation:Shape" xmi:id="_L4dhoPzlEeWmAaqzrMaEkA" type="3000">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_L4dhpPzlEeWmAaqzrMaEkA" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_L4dhpfzlEeWmAaqzrMaEkA" key="RegionZoneKey" value=""/>
</eAnnotations>
<children xmi:type="notation:DecorationNode" xmi:id="_L4dhovzlEeWmAaqzrMaEkA" type="3002">
<children xmi:type="notation:Shape" xmi:id="_L4evwPzlEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_L4evwvzlEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_McxvoPzlEeWmAaqzrMaEkA" width="81"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_L4evw_zlEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_L4evxPzlEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_L4evxfzlEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_L4evxvzlEeWmAaqzrMaEkA" y="-1" width="81"/>
</children>
<element xmi:type="uml:State" href="simple-submachine.uml#_L4eIsPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_L4evwfzlEeWmAaqzrMaEkA" x="120" y="17" width="81" height="78"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_OT9TsPzlEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_OT9TsvzlEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Qca1APzlEeWmAaqzrMaEkA" width="81"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_OT9Ts_zlEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_OT9TtPzlEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_OT9TtfzlEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_OT9TtvzlEeWmAaqzrMaEkA" y="-1" width="81"/>
</children>
<element xmi:type="uml:State" href="simple-submachine.uml#_OT30IPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_OT9TsfzlEeWmAaqzrMaEkA" x="300" y="17" width="81" height="81"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_VRiw4PzlEeWmAaqzrMaEkA" type="8000">
<children xmi:type="notation:DecorationNode" xmi:id="_VRjX8PzlEeWmAaqzrMaEkA" type="8001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_VRjX8fzlEeWmAaqzrMaEkA" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_VRjX8vzlEeWmAaqzrMaEkA" type="8002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_VRjX8_zlEeWmAaqzrMaEkA" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="simple-submachine.uml#_VRbcIPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_VRiw4fzlEeWmAaqzrMaEkA" x="25" y="36"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_L4dho_zlEeWmAaqzrMaEkA"/>
</children>
<element xmi:type="uml:Region" href="simple-submachine.uml#_L4c6kPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_L4dhofzlEeWmAaqzrMaEkA" width="421" height="118"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_EzEzVvzlEeWmAaqzrMaEkA" y="23" width="421" height="118"/>
</children>
<element xmi:type="uml:State" href="simple-submachine.uml#_EzBwAPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_EzEzUfzlEeWmAaqzrMaEkA" x="190" y="27" width="421" height="141"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_JTS2MPzlEeWmAaqzrMaEkA" type="6000">
<children xmi:type="notation:DecorationNode" xmi:id="_JTS2MvzlEeWmAaqzrMaEkA" type="6001">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KqmAUPzlEeWmAaqzrMaEkA" width="181"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_JTS2M_zlEeWmAaqzrMaEkA" type="19003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_JTS2NPzlEeWmAaqzrMaEkA" x="40"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_JTS2NfzlEeWmAaqzrMaEkA" type="6002">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_JTS2NvzlEeWmAaqzrMaEkA" y="-1" width="181"/>
</children>
<element xmi:type="uml:State" href="simple-submachine.uml#_JTOkwPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_JTS2MfzlEeWmAaqzrMaEkA" x="310" y="227" width="181"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_T0C4IPzlEeWmAaqzrMaEkA" type="8000">
<children xmi:type="notation:DecorationNode" xmi:id="_T0DfMPzlEeWmAaqzrMaEkA" type="8001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_T0DfMfzlEeWmAaqzrMaEkA" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_T0DfMvzlEeWmAaqzrMaEkA" type="8002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_T0DfM_zlEeWmAaqzrMaEkA" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="simple-submachine.uml#_Tz8KcPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_T0C4IfzlEeWmAaqzrMaEkA" x="50" y="54"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_AWUUKvzlEeWmAaqzrMaEkA"/>
</children>
<element xmi:type="uml:Region" href="simple-submachine.uml#_AWUUIPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_AWUUK_zlEeWmAaqzrMaEkA" width="700" height="286"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_AWUULPzlEeWmAaqzrMaEkA" y="23" width="700" height="287"/>
</children>
<element xmi:type="uml:StateMachine" href="simple-submachine.uml#_AWTGAPzlEeWmAaqzrMaEkA"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_AWUULfzlEeWmAaqzrMaEkA" x="30" y="30" width="700" height="310"/>
</children>
<styles xmi:type="notation:StringValueStyle" xmi:id="_AWUULvzlEeWmAaqzrMaEkA" name="diagram_compatibility_version" stringValue="1.1.0"/>
<styles xmi:type="notation:DiagramStyle" xmi:id="_AWUUL_zlEeWmAaqzrMaEkA"/>
<styles xmi:type="style:PapyrusViewStyle" xmi:id="_AWUUMPzlEeWmAaqzrMaEkA">
<owner xmi:type="uml:Model" href="simple-submachine.uml#_AWQCsPzlEeWmAaqzrMaEkA"/>
</styles>
<element xmi:type="uml:StateMachine" href="simple-submachine.uml#_AWTGAPzlEeWmAaqzrMaEkA"/>
<edges xmi:type="notation:Connector" xmi:id="_XMfaoPzlEeWmAaqzrMaEkA" type="7000" source="_T0C4IPzlEeWmAaqzrMaEkA" target="_EzEzUPzlEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_XMgBsvzlEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_XMgBs_zlEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_XMgBtPzlEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_XMgBtfzlEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_XMgBtvzlEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_XMgBt_zlEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_XMgBsPzlEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-submachine.uml#_XMT0cPzlEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_XMgBsfzlEeWmAaqzrMaEkA" points="[5, 7, -130, 0]$[135, 7, 0, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XM7fgPzlEeWmAaqzrMaEkA" id="(1.0,0.4)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XM7fgfzlEeWmAaqzrMaEkA" id="(0.0,0.28368794326241137)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_X4HxkPzlEeWmAaqzrMaEkA" type="7000" source="_VRiw4PzlEeWmAaqzrMaEkA" target="_L4evwPzlEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_X4Hxk_zlEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_X4HxlPzlEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_X4HxlfzlEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_X4HxlvzlEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_X4Hxl_zlEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_X4HxmPzlEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_X4HxkfzlEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-submachine.uml#_X38LYPzlEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_X4HxkvzlEeWmAaqzrMaEkA" points="[8, -1, -89, 0]$[85, -6, -12, -5]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_X4m5wPzlEeWmAaqzrMaEkA" id="(1.0,0.45)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_X4m5wfzlEeWmAaqzrMaEkA" id="(0.0,0.358974358974359)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_YfVikPzlEeWmAaqzrMaEkA" type="7000" source="_L4evwPzlEeWmAaqzrMaEkA" target="_OT9TsPzlEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_YfWJoPzlEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_YfWJofzlEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_YfWJovzlEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_YfWJo_zlEeWmAaqzrMaEkA" x="-2" y="-11"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_YfWJpPzlEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_YfWJpfzlEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_YfVikfzlEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-submachine.uml#_YfLxkPzlEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_YfVikvzlEeWmAaqzrMaEkA" points="[81, 23, -78, -24]$[140, 52, -19, 5]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_YfxAYPzlEeWmAaqzrMaEkA" id="(1.0,0.5128205128205128)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_YfxncPzlEeWmAaqzrMaEkA" id="(0.0,0.49382716049382713)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_ZgzmoPzlEeWmAaqzrMaEkA" type="7000" source="_EzEzUPzlEeWmAaqzrMaEkA" target="_JTS2MPzlEeWmAaqzrMaEkA">
<children xmi:type="notation:DecorationNode" xmi:id="_Zg0NsPzlEeWmAaqzrMaEkA" type="7001">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Zg0NsfzlEeWmAaqzrMaEkA"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_Zg0NsvzlEeWmAaqzrMaEkA" type="7002">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Zg0Ns_zlEeWmAaqzrMaEkA" x="-2" y="-29"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_Zg0NtPzlEeWmAaqzrMaEkA" type="7003">
<layoutConstraint xmi:type="notation:Location" xmi:id="_Zg0NtfzlEeWmAaqzrMaEkA" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_ZgzmofzlEeWmAaqzrMaEkA"/>
<element xmi:type="uml:Transition" href="simple-submachine.uml#_ZgnZYPzlEeWmAaqzrMaEkA"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZgzmovzlEeWmAaqzrMaEkA" points="[0, 0, 0, -59]$[0, 27, 0, -32]$[0, 59, 0, 0]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZhVLEPzlEeWmAaqzrMaEkA" id="(0.4750593824228028,1.0)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZhVLEfzlEeWmAaqzrMaEkA" id="(0.4419889502762431,0.0)"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_AWQCsPzlEeWmAaqzrMaEkA" name="RootElement">
<packagedElement xmi:type="uml:StateMachine" xmi:id="_AWTGAPzlEeWmAaqzrMaEkA" name="StateMachine">
<region xmi:type="uml:Region" xmi:id="_AWUUIPzlEeWmAaqzrMaEkA" name="Region1">
<transition xmi:type="uml:Transition" xmi:id="_XMT0cPzlEeWmAaqzrMaEkA" source="_Tz8KcPzlEeWmAaqzrMaEkA" target="_EzBwAPzlEeWmAaqzrMaEkA"/>
<transition xmi:type="uml:Transition" xmi:id="_ZgnZYPzlEeWmAaqzrMaEkA" source="_EzBwAPzlEeWmAaqzrMaEkA" target="_JTOkwPzlEeWmAaqzrMaEkA">
<trigger xmi:type="uml:Trigger" xmi:id="_p558APzlEeWmAaqzrMaEkA" event="_i4DC0PzlEeWmAaqzrMaEkA"/>
</transition>
<subvertex xmi:type="uml:State" xmi:id="_EzBwAPzlEeWmAaqzrMaEkA" name="S1">
<region xmi:type="uml:Region" xmi:id="_L4c6kPzlEeWmAaqzrMaEkA" name="Region1">
<transition xmi:type="uml:Transition" xmi:id="_X38LYPzlEeWmAaqzrMaEkA" source="_VRbcIPzlEeWmAaqzrMaEkA" target="_L4eIsPzlEeWmAaqzrMaEkA"/>
<transition xmi:type="uml:Transition" xmi:id="_YfLxkPzlEeWmAaqzrMaEkA" source="_L4eIsPzlEeWmAaqzrMaEkA" target="_OT30IPzlEeWmAaqzrMaEkA">
<trigger xmi:type="uml:Trigger" xmi:id="_mJnhQPzlEeWmAaqzrMaEkA" event="_fofWkPzlEeWmAaqzrMaEkA"/>
</transition>
<subvertex xmi:type="uml:State" xmi:id="_L4eIsPzlEeWmAaqzrMaEkA" name="S11"/>
<subvertex xmi:type="uml:State" xmi:id="_OT30IPzlEeWmAaqzrMaEkA" name="S12"/>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_VRbcIPzlEeWmAaqzrMaEkA"/>
</region>
</subvertex>
<subvertex xmi:type="uml:State" xmi:id="_JTOkwPzlEeWmAaqzrMaEkA" name="S2"/>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_Tz8KcPzlEeWmAaqzrMaEkA"/>
</region>
</packagedElement>
<packagedElement xmi:type="uml:Signal" xmi:id="_cKuPMPzlEeWmAaqzrMaEkA" name="E1"/>
<packagedElement xmi:type="uml:Signal" xmi:id="_eCEyYPzlEeWmAaqzrMaEkA" name="E2"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_fofWkPzlEeWmAaqzrMaEkA" name="SignalEvent1" signal="_cKuPMPzlEeWmAaqzrMaEkA"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_i4DC0PzlEeWmAaqzrMaEkA" name="SignalEvent2" signal="_eCEyYPzlEeWmAaqzrMaEkA"/>
</uml:Model>