Missing spel effect with transition in uml

- Add missing resolve/create for action if type is defined as spel.
- Forward port #889
This commit is contained in:
Janne Valkealahti
2020-11-22 08:51:16 +00:00
parent c7debc39f4
commit 56e3abf132
5 changed files with 169 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2016-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,9 +37,14 @@ import org.eclipse.uml2.uml.Transition;
import org.eclipse.uml2.uml.Trigger;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.springframework.expression.spel.SpelCompilerMode;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.action.SpelExpressionAction;
import org.springframework.statemachine.config.model.StateMachineComponentResolver;
import org.springframework.statemachine.transition.TransitionKind;
import org.springframework.util.StringUtils;
/**
* Utilities for uml model processing.
@@ -138,9 +143,18 @@ public abstract class UmlUtils {
Action<String, String> action = null;
if (transition.getEffect() instanceof OpaqueBehavior) {
String beanId = UmlUtils.resolveBodyByLanguage(UmlModelParser.LANGUAGE_BEAN, (OpaqueBehavior)transition.getEffect());
Action<String, String> bean = resolver.resolveAction(beanId);
if (bean != null) {
action = bean;
if (StringUtils.hasText(beanId)) {
Action<String, String> bean = resolver.resolveAction(beanId);
if (bean != null) {
action = bean;
}
} else {
String expression = UmlUtils.resolveBodyByLanguage(UmlModelParser.LANGUAGE_SPEL, (OpaqueBehavior)transition.getEffect());
if (StringUtils.hasText(expression)) {
SpelExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.MIXED, null));
action = new SpelExpressionAction<String, String>(parser.parseExpression(expression));
}
}
}
return action;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2020 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.
@@ -1122,6 +1122,20 @@ public class UmlStateMachineModelFactoryTests extends AbstractUmlTests {
assertThat(choiceStateData.getParent(), is("S1"));
}
@Test
@SuppressWarnings("unchecked")
public void testTransitionEffectSpel() {
context.register(Config27.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
assertThat(stateMachine.getExtendedState().get("key", String.class), is("value"));
}
@Configuration
@EnableStateMachine
public static class Config2 extends StateMachineConfigurerAdapter<String, String> {
@@ -1759,6 +1773,24 @@ public class UmlStateMachineModelFactoryTests extends AbstractUmlTests {
}
@Configuration
@EnableStateMachine
public static class Config27 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/transition-effect-spel.uml");
return new UmlStateMachineModelFactory(model);
}
}
public static class LatchAction implements Action<String, String> {
CountDownLatch latch = new CountDownLatch(1);
@Override

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/>

View File

@@ -0,0 +1,93 @@
<?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.3/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_WX9kECwNEeufCYvq_3Ps8A" type="PapyrusUMLStateMachineDiagram" name="State Machine Diagram" measurementUnit="Pixel">
<children xmi:type="notation:Shape" xmi:id="_WX9kESwNEeufCYvq_3Ps8A" type="StateMachine_Shape">
<children xmi:type="notation:DecorationNode" xmi:id="_WX9kEiwNEeufCYvq_3Ps8A" type="StateMachine_NameLabel">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_WX9kEywNEeufCYvq_3Ps8A" width="700" height="20"/>
</children>
<children xmi:type="notation:BasicCompartment" xmi:id="_WX9kFCwNEeufCYvq_3Ps8A" type="StateMachine_RegionCompartment">
<children xmi:type="notation:Shape" xmi:id="_WX9kFSwNEeufCYvq_3Ps8A" type="Region_Shape">
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_WX9kFiwNEeufCYvq_3Ps8A" source="RegionAnnotationKey">
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_WX9kFywNEeufCYvq_3Ps8A" key="RegionZoneKey" value=""/>
</eAnnotations>
<children xmi:type="notation:BasicCompartment" xmi:id="_WX9kGCwNEeufCYvq_3Ps8A" type="Region_SubvertexCompartment">
<children xmi:type="notation:Shape" xmi:id="_3XeYACyPEeu3_ZAvzk8Jfg" type="State_Shape">
<children xmi:type="notation:DecorationNode" xmi:id="_3XfmICyPEeu3_ZAvzk8Jfg" type="State_NameLabel"/>
<children xmi:type="notation:DecorationNode" xmi:id="_3XfmISyPEeu3_ZAvzk8Jfg" type="State_FloatingNameLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_3XfmIiyPEeu3_ZAvzk8Jfg" x="40"/>
</children>
<children xmi:type="notation:BasicCompartment" xmi:id="_3XgNMCyPEeu3_ZAvzk8Jfg" type="State_RegionCompartment">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3XgNMSyPEeu3_ZAvzk8Jfg"/>
</children>
<element xmi:type="uml:State" href="transition-effect-spel.uml#_3XXDQCyPEeu3_ZAvzk8Jfg"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3XeYASyPEeu3_ZAvzk8Jfg" x="114" y="71"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_5BEMACyPEeu3_ZAvzk8Jfg" type="State_Shape">
<children xmi:type="notation:DecorationNode" xmi:id="_5BEzECyPEeu3_ZAvzk8Jfg" type="State_NameLabel"/>
<children xmi:type="notation:DecorationNode" xmi:id="_5BEzESyPEeu3_ZAvzk8Jfg" type="State_FloatingNameLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_5BEzEiyPEeu3_ZAvzk8Jfg" x="40"/>
</children>
<children xmi:type="notation:BasicCompartment" xmi:id="_5BEzEyyPEeu3_ZAvzk8Jfg" type="State_RegionCompartment">
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_5BEzFCyPEeu3_ZAvzk8Jfg"/>
</children>
<element xmi:type="uml:State" href="transition-effect-spel.uml#_5A6bACyPEeu3_ZAvzk8Jfg"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_5BEMASyPEeu3_ZAvzk8Jfg" x="229" y="70"/>
</children>
<children xmi:type="notation:Shape" xmi:id="_65shkCyPEeu3_ZAvzk8Jfg" type="Pseudostate_InitialShape">
<children xmi:type="notation:DecorationNode" xmi:id="_65tIoCyPEeu3_ZAvzk8Jfg" type="Pseudostate_InitialFloatingNameLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_65tvsCyPEeu3_ZAvzk8Jfg" x="25" y="3"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_65tvsSyPEeu3_ZAvzk8Jfg" type="Pseudostate_InitialStereotypeLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_65tvsiyPEeu3_ZAvzk8Jfg" x="25" y="-10"/>
</children>
<element xmi:type="uml:Pseudostate" href="transition-effect-spel.uml#_65dRACyPEeu3_ZAvzk8Jfg"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_65shkSyPEeu3_ZAvzk8Jfg" x="29" y="70"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_WX9kGSwNEeufCYvq_3Ps8A"/>
</children>
<element xmi:type="uml:Region" href="transition-effect-spel.uml#_WX4rkCwNEeufCYvq_3Ps8A"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_WX9kGiwNEeufCYvq_3Ps8A" width="700" height="280"/>
</children>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_WX9kGywNEeufCYvq_3Ps8A" y="20" width="700" height="280"/>
</children>
<element xmi:type="uml:StateMachine" href="transition-effect-spel.uml#_WXLg8CwNEeufCYvq_3Ps8A"/>
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_WX9kHCwNEeufCYvq_3Ps8A" x="30" y="30" width="700" height="300"/>
</children>
<styles xmi:type="notation:StringValueStyle" xmi:id="_WX9kHSwNEeufCYvq_3Ps8A" name="diagram_compatibility_version" stringValue="1.4.0"/>
<styles xmi:type="notation:DiagramStyle" xmi:id="_WX9kHiwNEeufCYvq_3Ps8A"/>
<styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_WX9kHywNEeufCYvq_3Ps8A" diagramKindId="org.eclipse.papyrus.uml.diagram.stateMachine">
<owner xmi:type="uml:Model" href="transition-effect-spel.uml#_WWYPsCwNEeufCYvq_3Ps8A"/>
</styles>
<element xmi:type="uml:StateMachine" href="transition-effect-spel.uml#_WXLg8CwNEeufCYvq_3Ps8A"/>
<edges xmi:type="notation:Connector" xmi:id="_9UCdECyPEeu3_ZAvzk8Jfg" type="Transition_Edge" source="_65shkCyPEeu3_ZAvzk8Jfg" target="_3XeYACyPEeu3_ZAvzk8Jfg">
<children xmi:type="notation:DecorationNode" xmi:id="_9UESQCyPEeu3_ZAvzk8Jfg" type="Transition_NameLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_9UESQSyPEeu3_ZAvzk8Jfg" y="20"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_9UESQiyPEeu3_ZAvzk8Jfg" type="Transition_GuardLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_9UESQyyPEeu3_ZAvzk8Jfg" y="-20"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_9UESRCyPEeu3_ZAvzk8Jfg" type="Transition_StereotypeLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_9UE5UCyPEeu3_ZAvzk8Jfg" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_9UCdESyPEeu3_ZAvzk8Jfg"/>
<element xmi:type="uml:Transition" href="transition-effect-spel.uml#_9SLb4CyPEeu3_ZAvzk8Jfg"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9UCdEiyPEeu3_ZAvzk8Jfg" points="[78, 131, -643984, -643984]$[145, 140, -643984, -643984]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_9VAGYCyPEeu3_ZAvzk8Jfg" id="(0.9,0.5596774193548384)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_9VAGYSyPEeu3_ZAvzk8Jfg" id="(0.0,0.4318181818181818)"/>
</edges>
<edges xmi:type="notation:Connector" xmi:id="_-G6EcCyPEeu3_ZAvzk8Jfg" type="Transition_Edge" source="_3XeYACyPEeu3_ZAvzk8Jfg" target="_5BEMACyPEeu3_ZAvzk8Jfg">
<children xmi:type="notation:DecorationNode" xmi:id="_-G6EcyyPEeu3_ZAvzk8Jfg" type="Transition_NameLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_-G6EdCyPEeu3_ZAvzk8Jfg" y="20"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_-G6EdSyPEeu3_ZAvzk8Jfg" type="Transition_GuardLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_-G6EdiyPEeu3_ZAvzk8Jfg" y="-20"/>
</children>
<children xmi:type="notation:DecorationNode" xmi:id="_-G6rgCyPEeu3_ZAvzk8Jfg" type="Transition_StereotypeLabel">
<layoutConstraint xmi:type="notation:Location" xmi:id="_-G6rgSyPEeu3_ZAvzk8Jfg" y="60"/>
</children>
<styles xmi:type="notation:FontStyle" xmi:id="_-G6EcSyPEeu3_ZAvzk8Jfg"/>
<element xmi:type="uml:Transition" href="transition-effect-spel.uml#_-GvFUCyPEeu3_ZAvzk8Jfg"/>
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_-G6EciyPEeu3_ZAvzk8Jfg" points="[185, 140, -643984, -643984]$[260, 140, -643984, -643984]"/>
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_-HX-gCyPEeu3_ZAvzk8Jfg" id="(1.0,0.4318181818181818)"/>
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_-HX-gSyPEeu3_ZAvzk8Jfg" id="(0.0,0.45454545454545453)"/>
</edges>
</notation:Diagram>

View File

@@ -0,0 +1,23 @@
<?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="_WWYPsCwNEeufCYvq_3Ps8A" name="transition-effect-spel">
<packageImport xmi:type="uml:PackageImport" xmi:id="_WZq0QCwNEeufCYvq_3Ps8A">
<importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
</packageImport>
<packagedElement xmi:type="uml:StateMachine" xmi:id="_WXLg8CwNEeufCYvq_3Ps8A" name="StateMachine">
<region xmi:type="uml:Region" xmi:id="_WX4rkCwNEeufCYvq_3Ps8A" name="Region1">
<transition xmi:type="uml:Transition" xmi:id="_9SLb4CyPEeu3_ZAvzk8Jfg" source="_65dRACyPEeu3_ZAvzk8Jfg" target="_3XXDQCyPEeu3_ZAvzk8Jfg"/>
<transition xmi:type="uml:Transition" xmi:id="_-GvFUCyPEeu3_ZAvzk8Jfg" source="_3XXDQCyPEeu3_ZAvzk8Jfg" target="_5A6bACyPEeu3_ZAvzk8Jfg">
<effect xmi:type="uml:OpaqueBehavior" xmi:id="_nAgpQCySEeu3_ZAvzk8Jfg">
<language>spel</language>
<body>extendedState.variables.put('key','value')</body>
</effect>
<trigger xmi:type="uml:Trigger" xmi:id="_6JohICyQEeu3_ZAvzk8Jfg" name="Trigger1" event="_RG01oCyREeu3_ZAvzk8Jfg"/>
</transition>
<subvertex xmi:type="uml:State" xmi:id="_3XXDQCyPEeu3_ZAvzk8Jfg" name="S1"/>
<subvertex xmi:type="uml:State" xmi:id="_5A6bACyPEeu3_ZAvzk8Jfg" name="S2"/>
<subvertex xmi:type="uml:Pseudostate" xmi:id="_65dRACyPEeu3_ZAvzk8Jfg" name=""/>
</region>
</packagedElement>
<packagedElement xmi:type="uml:Signal" xmi:id="_z8mzoCyPEeu3_ZAvzk8Jfg" name="E1"/>
<packagedElement xmi:type="uml:SignalEvent" xmi:id="_RG01oCyREeu3_ZAvzk8Jfg" name="SignalEventE1" signal="_z8mzoCyPEeu3_ZAvzk8Jfg"/>
</uml:Model>