|
From: David H. <dh...@ob...> - 2005-04-26 08:32:39
|
Keith,
On=20transition=20actions,=20I=20can=20see=20the=20benefits=20and=20I=20th=
ink=20I=20would=20use=20them,=20but=20quite=20often=20my=20view-states=20a=
re=20not=20simple=20enough=20for=20this=20feature.=20For=20example,=20if=20=
I=20have=20some=20action=20that=20I=20always=20invoke=20before=20continuin=
g=20to=20the=20view-state=20that=20populates=20the=20request=20with=20some=
=20necessary=20(but=20short-lived)=20reference=20data.With=20a=20transitio=
n=20action=20that=20just=20redisplays=20the=20current=20view-state,=20that=
=20action=20would=20be=20skipped=20and=20the=20reference=20data=20not=20ma=
de=20available=20in=20the=20request.=20What=20would=20be=20really=20nice=20=
would=20be=20a=20kind=20of=20setup=20action=20property=20of=20the=20view-s=
tate,=20for=20preparing=20data=20that=20the=20view=20depends=20on.=20Faili=
ng=20that,=20perhaps=20if=20you=20were=20able=20to=20specify=20a=20specifi=
c=20outcome=20state=20on=20failure,=20rather=20than=20just=20returning=20t=
o=20the=20current=20view.=20
=20
I=20like=20the=20decision=20state=20a=20lot=20as=20I=20frequently=20have=20=
long=20wizards=20with=20several=20optional=20steps,=20and=20making=20decis=
ions=20a=20first=20class=20citizen=20makes=20scanning=20the=20flow=20xml=20=
much=20clearer.=20My=20one=20gripe=20that=20I've=20always=20had=20is=20tha=
t=20if=20I=20have=20a=20bidirectional=20wizard=20with=20a=20step=20that=20=
can=20be=20skipped=20under=20some=20condition,=20I=20have=20to=20check=20s=
eparately=20when=20moving=20forwards=20and=20backwards.=20So,=20if=20your=20=
showCostOverview=20state=20were=20a=20regular=20view-state,=20you=20might=20=
have=20a=20'back'=20transition=20that=20would=20need=20to=20hit=20a=20sepa=
rate=20decision=20like:
=20
=20=20=20<decision-state=20id=3D"requiresShippingBackwards">=20
=20=20=20=20=20=20<if=20test=3D"${flowScope.sale.shipping}"=20then=3D"ente=
rShippingDetails"=20else=3D"enterCategory"/>=20
=20=20=20</decision-state>=20
=20
I=20don't=20know=20of=20a=20way=20round=20this,=20although=20something=20l=
ike=20the=20following=20is=20close=20to=20what=20I=20want=20to=20do:
=20
=20=20=20<action-state=20id=3D"requiresShipping">=20
=20=20=20=20=20=20<action=20class=3D"org.springframework.web.flow.action.D=
ecisionAction">=20
=20=20=20=20=20=20=20=20=20<property=20name=3D"criteria"=20value=3D"${flow=
Scope.sale.shipping}"/>=20
=20=20=20=20=20=20</action>=20
=20=20=20=20=20=20<transition=20on=3D"required"=20to=3D"enterShippingDetai=
ls"/>=20
=20=20=20=20=20=20<transition=20on=3D"skipForward"=20to=3D"showCostOvervie=
w"/>=20
=20=20=20=20=20=20<transition=20on=3D"skipBackward"=20to=3D"enteryCategory=
"/>=20
=20=20=20</action-state>=20
=20
This=20would=20require=20the=20action=20to=20be=20aware=20of=20some=20para=
meter=20indicating=20directionality=20that=20you=20would=20have=20to=20sup=
ply=20in=20the=20invoking=20state=20or=20action.=20Right=20now,=20I'm=20ha=
ppy=20with=20duplicating=20decisions,=20especially=20given=20the=20tersene=
ss=20of=20the=20definition,=20but=20if=20you=20have=20a=20solution=20I'd=20=
be=20keen=20to=20hear=20it!
=20
-Dave
________________________________
From:=20s...@li...=20on=20behal=
f=20of=20Keith=20Donald
Sent:=20Mon=2025/04/2005=2007:26
To:=20s...@li...
Subject:=20[Springframework-developer]=20SWF=20PR3=20features=20-=20seekin=
g=20feedback
The=20SWF=20team=20has=20gotten=20closer=20to=20finalizing=20the=20major=20=
new=20features=20for=20PR3.=20=20After=20debating=20these=20vigorously=20t=
his=20weekend,=20we're=20pretty=20happy=20with=20them-but=20are=20seeking=20=
additional=20feedback.
Here=20they=20are,=20all=20available=20now=20in=20CVS:=20
-=20Transition=20actions:=20on=20the=20occurrence=20of=20an=20event,=20thi=
s=20provides=20the=20ability=20to=20execute=20an=20action=20after=20a=20st=
ate=20transition=20is=20matched=20but=20before=20the=20transition=20is=20e=
xecuted.=20=20In=20this=20case,=20the=20action=20result=20event=20is=20ada=
pted=20to=20a=20boolean=20expression--if=20true,=20the=20transition=20to=20=
the=20target=20state=20proceeds,=20if=20false,=20the=20current=20state=20i=
s=20re-entered.=20By=20default=20a=20'success'=20action=20result=20is=20ma=
pped=20to=20true,=20anything=20else=20is=20mapped=20to=20false.
The=20biggest=20use-case=20for=20this=20is=20in=20executing=20so-called=20=
'cross-cutting'=20actions=20that=20have=20a=20logical=20'success'=20or=20'=
error'=20result=20--=20like=20bindAndValidate.=20
Here's=20an=20example:=20
Code:
=20=20=20<view-state=20id=3D"enterPriceAndItemCount"=20view=3D"priceAndIte=
mCountForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"enterCategory">=20
=20=20=20=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"b=
indAndValidate">=20
=20=20=20=20=20=20=20=20=20=20=20=20<property=20name=3D"validatorMethod"=20=
value=3D"validatePriceAndItemCount"/>=20
=20=20=20=20=20=20=20=20=20</action>=20
=20=20=20=20=20=20</transition>=20
=20=20=20</view-state>=20
This=20reduces=20flow=20def=20LoC=20substantially=20in=20the=20typical=20'=
wizard'=20flow=20cases,=20as=20previously=20you=20were=20forced=20to=20def=
ine=20a=20separate=20action=20state=20for=20each=20ViewState=20needing=20'=
on=20submit'=20bindAndValidate=20behaivior.=20
-=20Enhanced=20FlowExecutionListener=20lifecycle=20callbacks,=20including=20=
new=20'flowStarting',=20and=20'stateEntering'=20and=20'stateEntered'=20met=
hods.=20The=20first=20two=20can=20be=20used=20to=20test=20state=20precondi=
tions=20(invariants=20that=20must=20hold=20true=20for=20a=20new=20state=20=
to=20be=20allowed=20to=20enter).=20'stateEntered'=20can=20be=20used=20to=20=
test=20state=20postconditions=20(invariants=20that=20must=20hold=20true=20=
after=20a=20state=20has=20entered).=20The=20new=20'StateConditionTester'=20=
strategy=20makes=20this=20easily=20pluggable=20behind=20a=20simple=20facad=
e=20interface.=20'Sell=20item'=20demonstrates=20this=20in=20CVS=20now-spec=
ifically,=20treating=20a=20user=20role-security-check=20as=20a=20state=20p=
recondition.
-=20State=20properties.=20States=20can=20now=20have=20arbitrary=20property=
=20metadata,=20just=20like=20actions.=20For=20example:=20
Code:
=20=20=20<action-state=20id=3D"setupForm">=20
=20=20=20=20=20=20<action=20bean=3D"sellItemAction"/>=20
=20=20=20=20=20=20<transition=20on=3D"success"=20to=3D"enterPriceAndItemCo=
unt"/>=20
=20=20=20=20=20=20<property=20name=3D"role"=20value=3D"manager"/>=20
=20=20=20</action-state>=20
The=20above=20example=20assigns=20the=20'role'=20property=20to=20the=20'se=
tupForm'=20state=20with=20value=20'manager'.=20
State=20properties=20can=20be=20reasoned=20on=20by=20StateConditionTesters=
,=20views,=20or=20actions.=20For=20example,=20the=20SellItemStateCondition=
Tester=20checks=20the=20'role'=20property=20for=20the=20state=20that=20has=
=20been=20requested=20to=20enter=20and=20verifies=20the=20authenticated=20=
user=20has=20that=20role=20before=20allowing=20the=20state=20transition=20=
to=20complete.=20
-=20A=20decision=20state=20and=20a=20decision=20action.=20These=20construc=
ts=20allow=20you=20to=20evaluate=20one=20or=20more=20expressions=20to=20de=
cide=20"where=20to=20go=20next"=20in=20a=20reusable=20way:=20
The=20decision=20state:=20
Code:
=20=20=20<decision-state=20id=3D"requiresShipping">=20
=20=20=20=20=20=20<if=20test=3D"${flowScope.sale.shipping}"=20then=3D"ente=
rShippingDetails"=20else=3D"showCostOverview"/>=20
=20=20=20</decision-state>=20
The=20equivalent=20decision=20action:=20
Code:
=20=20=20<action-state=20id=3D"requiresShipping">=20
=20=20=20=20=20=20<action=20class=3D"org.springframework.web.flow.action.D=
ecisionAction">=20
=20=20=20=20=20=20=20=20=20<property=20name=3D"criteria"=20value=3D"${flow=
Scope.sale.shipping}"/>=20
=20=20=20=20=20=20</action>=20
=20=20=20=20=20=20<transition=20on=3D"true"=20to=3D"enterShippingDetails"/=
>=20
=20=20=20=20=20=20<transition=20on=3D"false"=20to=3D"showCostOverview"/>=20=
=20=20=20</action-state>=20
Erwin=20and=20I=20have=20debated=20whether=20we=20really=20need=20first=20=
class=20support=20for=20the=20decision=20state=20(as=20you=20could=20use=20=
the=20DecisionAction=20from=20a=20action=20state),=20but=20it=20just=20see=
ms=20so=20elegant=20and=20sexy=20and=20flexible,=20with=20little=20introdu=
ced=20complexity--so=20right=20now=20we=20feel=20its=20a=20keeper.=20Pleas=
e=20let=20us=20know=20if=20you=20agree=20or=20disagree.
Putting=20it=20all=20together,=20from=20sell=20item:=20
Before=20new=20PR3=20features:=20
Code:
<?xml=20version=3D"1.0"=20encoding=3D"UTF-8"?>=20
<!DOCTYPE=20webflow=20PUBLIC=20"-//SPRING//DTD=20WEBFLOW//EN"=20
=20=20=20"http://www.springframework.org/dtd/spring-webflow.dtd">=20
<webflow=20id=3D"sellItem"=20start-state=3D"setupForm">=20
=20=20=20<action-state=20id=3D"setupForm">=20
=20=20=20=20=20=20<action=20bean=3D"sellItemAction"/>=20
=20=20=20=20=20=20<transition=20on=3D"success"=20to=3D"enterPriceAndItemCo=
unt"/>=20
=20=20=20</action-state>=20
=20=20=20<view-state=20id=3D"enterPriceAndItemCount"=20view=3D"priceAndIte=
mCountForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"bindAndValidatePrice=
AndItemCount"/>=20
=20=20=20</view-state>=20
=20=20=20=20
=20=20=20<action-state=20id=3D"bindAndValidatePriceAndItemCount">=20
=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"bindAndVal=
idate">=20
=20=20=20=20=20=20=20=20=20<property=20name=3D"validatorMethod"=20value=3D=
"validatePriceAndItemCount"/>=20
=20=20=20=20=20=20</action>=20
=20=20=20=20=20=20<transition=20on=3D"success"=20to=3D"enterCategory"/>=20=
=20=20=20=20=20=20<transition=20on=3D"error"=20to=3D"enterPriceAndItemCoun=
t"/>=20
=20=20=20</action-state>=20
=20=20=20=20
=20=20=20<view-state=20id=3D"enterCategory"=20view=3D"categoryForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"bindAndValidateCateg=
ory"/>=20
=20=20=20</view-state>=20
=20=20=20<action-state=20id=3D"bindAndValidateCategory">=20
=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"bindAndVal=
idate"/>=20
=20=20=20=20=20=20<transition=20on=3D"${#result=20=3D=3D=20'success'=20and=
=20flowScope.sale.shipping}"=20to=3D"enterShippingDetails"/>=20
=20=20=20=20=20=20<transition=20on=3D"${#result=20=3D=3D=20'success'=20and=
=20!flowScope.sale.shipping}"=20to=3D"showCostOverview"/>=20
=20=20=20=20=20=20<transition=20on=3D"error"=20to=3D"enterCategory"/>=20
=20=20=20</action-state>=20
=20=20=20=20
=20=20=20<view-state=20id=3D"enterShippingDetails"=20view=3D"shippingDetai=
lsForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"bindAndValidateShipp=
ingDetails"/>=20
=20=20=20</view-state>=20
=20=20=20<action-state=20id=3D"bindAndValidateShippingDetails">=20
=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"bindAndVal=
idate"/>=20
=20=20=20=20=20=20<transition=20on=3D"success"=20to=3D"showCostOverview"/>=
=20
=20=20=20=20=20=20<transition=20on=3D"error"=20to=3D"enterShippingDetails"=
/>=20
=20=20=20</action-state>=20
=20=20=20=20
=20=20=20<end-state=20id=3D"showCostOverview"=20view=3D"costOverview"/>=20=
</webflow>=20
After=20New=20PR3=20Features:
Code:
<webflow=20id=3D"sellItem"=20start-state=3D"setupForm">=20
=20=20=20<action-state=20id=3D"setupForm">=20
=20=20=20=20=20=20<action=20bean=3D"sellItemAction"/>=20
=20=20=20=20=20=20<transition=20on=3D"success"=20to=3D"enterPriceAndItemCo=
unt"/>=20
=20=20=20=20=20=20<property=20name=3D"role"=20value=3D"manager"/>=20
=20=20=20</action-state>=20
=20=20=20<view-state=20id=3D"enterPriceAndItemCount"=20view=3D"priceAndIte=
mCountForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"enterCategory">=20
=20=20=20=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"b=
indAndValidate">=20
=20=20=20=20=20=20=20=20=20=20=20=20<property=20name=3D"validatorMethod"=20=
value=3D"validatePriceAndItemCount"/>=20
=20=20=20=20=20=20=20=20=20</action>=20
=20=20=20=20=20=20</transition>=20
=20=20=20</view-state>=20
=20=20=20<view-state=20id=3D"enterCategory"=20view=3D"categoryForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"requiresShipping">=20=
=20=20=20=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"b=
indAndValidate"/>=20
=20=20=20=20=20=20</transition>=20
=20=20=20</view-state>=20
=20=20=20<decision-state=20id=3D"requiresShipping">=20
=20=20=20=20=20=20<if=20test=3D"${flowScope.sale.shipping}"=20then=3D"ente=
rShippingDetails"=20else=3D"showCostOverview"/>=20
=20=20=20</decision-state>=20
=20=20=20<view-state=20id=3D"enterShippingDetails"=20view=3D"shippingDetai=
lsForm">=20
=20=20=20=20=20=20<transition=20on=3D"submit"=20to=3D"showCostOverview">=20=
=20=20=20=20=20=20=20=20=20<action=20bean=3D"sellItemAction"=20method=3D"b=
indAndValidate"/>=20
=20=20=20=20=20=20</transition>=20
=20=20=20</view-state>=20
=20=20=20<end-state=20id=3D"showCostOverview"=20view=3D"costOverview"/>=20=
</webflow>=20
_________________
Keith=20Donald=20
Interface21=20-=20http://www.springframework.com=20-=20Spring=20Training,=20=
Consulting,=20and=20Support=20-=20"From=20the=20Source"
________________________________________________________________________
This=20e-mail=20has=20been=20scanned=20for=20all=20viruses=20by=20Star.=20=
The
service=20is=20powered=20by=20MessageLabs.=20For=20more=20information=20on=
=20a=20proactive
anti-virus=20service=20working=20around=20the=20clock,=20around=20the=20gl=
obe,=20visit:
http://www.star.net.uk
________________________________________________________________________
________________________________________________________________________
This=20e-mail=20has=20been=20scanned=20for=20all=20viruses=20by=20Star.=20=
The
service=20is=20powered=20by=20MessageLabs.=20For=20more=20information=20on=
=20a=20proactive
anti-virus=20service=20working=20around=20the=20clock,=20around=20the=20gl=
obe,=20visit:
http://www.star.net.uk
________________________________________________________________________ |