Flowscript - PowerPoint PPT Presentation

About This Presentation
Title:

Flowscript

Description:

Quickly becomes complex, hard to understand and to maintain ... FormValidatorAction, Precept, XMLForm, JXForms - 22 - Woody principles. The big picture ... – PowerPoint PPT presentation

Number of Views:30
Avg rating:3.0/5.0
Slides: 47
Provided by: sylvain95
Category:

less

Transcript and Presenter's Notes

Title: Flowscript


1
Flowscript WoodyWebapps made easy with Cocoon
  • Sylvain Wallezhttp//apache.org/sylvain

2
Flowscript intro
  • Flow control in Cocoon
  • Aren't actions enough ?
  • Yes, but they require state management
  • Quickly becomes complex, hard to understand and
    to maintain
  • ? Actions are the traditional "MVC" controller
  • Flowscript is a controller
  • Calls business logic and chooses the view
  • but also more
  • Keeps the application state
  • Describes page flow as a sequential program
  • Easily defines complex interactions

3
Flowscript intro
  • Flow script example

var cart var user function checkout()
while(user null) cocoon.sendPageAndWait("
login.html") user UserRegistry.getUser(coc
oon.request.get("name"))
cocoon.sendPageAndWait("shippingAddress.html",
who user) var address cocoon.request.get(
"address") cocoon.sendPageAndWait("creditCard.h
tml") var creditCard cocoon.request.get("cre
ditCard") cocoon.sendPageAndWait("confirmOrder.
html") EnterpriseSystem.placeOrder(user,
cart, address, creditCard) cocoon.sendPage("ord
erPlaced.html")
4
Flowscript intro
  • Why JavaScript ?
  • Simpler than Java, although powerful
  • Integrates well with Java
  • Well-known in the web world
  • Allows faster roundtrips (save and reload)
  • Supports continuations

5
Calling the view
  • cocoon.sendPage()
  • cocoon.sendPage invokes the output page (view)
    with two arguments
  • The view URL, relative to current sitemap
  • A context object made available to the view
  • ? Can be a Java or JavaScript object
  • cocoon.sendPage("view.html") is like redirecting
    to "cocoon/view.html"
  • Control then comes back to the script
  • ? Should normally terminate

cocoon.sendPage("checkout.html", user
loggedUser, email address)
6
Calling the view
  • cocoon.sendPageAndWait()
  • Similar to cocoon.sendPage
  • Invoke the view with a context object
  • The script is suspended after the view is
    generated
  • ? the whole execution stack saved in a
    continuation object
  • Flow between pages becomes sequential code
  • ? No more complicated state automata

7
Continuations
  • What is it ?
  • Contents of a continuation
  • Stack of function calls
  • Value of local variables
  • ? Most often a lightweight object
  • ? Creating a continuation does not halt a thread
    !!
  • A continuation object is associated with a unique
    identifier available to the view
  • ? Later used to "resurrect" it

8
Continuations
  • Sample flow script revisited

var cart var user function checkout()
while(user null) cocoon.sendPageAndWait("
login.html") user UserRegistry.getUser(coc
oon.request.get("name"))
cocoon.sendPageAndWait("shippingAddress.html",
who user) var address cocoon.request.get(
"address") cocoon.sendPageAndWait("creditCard.h
tml") var creditCard cocoon.request.get("cre
ditCard") cocoon.sendPageAndWait("confirmOrder.
html") EnterpriseSystem.placeOrder(user,
cart, address, creditCard) cocoon.sendPage("ord
erPlaced.html")
9
View layer
  • How to define the view ?
  • It's a regular Cocoon pipeline
  • ? Preferably in an internal-only"true" pipeline
  • Two generators providing tight integration
  • JXTemplateGenerator
  • JPath XSP logicsheet
  • ? Easy access to the context object

10
View layer
  • JXTemplateGenerator
  • An XML template language inspired by JSTL
  • Doesn't allow code, but only access to context
    variables
  • ? Simpler than XSP
  • Flow values are provided as variables
  • Two expressions languages
  • Jexl with and JXPath with

sendPage("checkout.html", "customer"
user, "cart" cart)
ltpgtWelcome, customer/firstNamelt/pgt
11
View layer
  • JXTemplate example

Your cart ltulgt ltjxforEach var"item"
items"cart.items"gt ltligtitem.quantity
item.namelt/ligt lt/jxforEachgt lt/ulgt lta
href"kont/continuation.id"gtContinuelt/agt
Your cart ltulgt ltligt3 Cocoon T-Shirtlt/ligt
ltligt1 Washing machinelt/ligt lt/ulgt lta
href"kont/bf6c433aa3148f8ca083f18a83813f81"gtConti
nuelt/agt
Will "resurrect" the flow script
12
Putting it all together
ltmappipelinesgt ltmappipelinegt ltmapmatch
pattern"checkout"gt ltmapcall
function"checkout"/gt lt/mapmatchgt
ltmapmatch pattern"kont/"gt ltmapcall
continuation"1"/gt lt/mapmatchgt
lt/mappipelinegt ltmappipeline
internal-only"true"gt ltmapmatch
pattern".html"/gt ltmapgenerate type"jxt"
src"1.xml"/gt ltmaptransform
src"page2html.xsl"/gt ltmapserialize/gt
lt/mapmatchgt /
? Call a flow function
? Resurrect a continuation
? View called by the flow
13
Putting it all together
  • FOM the Flow Object Model
  • Provided by the "cocoon" global object
  • Access to the environment
  • "request", "response", "session" "context"
    properties
  • "parameters" sitemap parameters
  • Access to the framework
  • Logging, using Avalon components
  • Page flow control
  • cocoon.sendPage(), cocoon.sendPageAndWait()
  • cocoon.redirectTo()

14
Session variables
  • Global scope session scope
  • Global variables are attached to the session
  • Saved across top-level function invocations
  • Specific to each user
  • ? Removes most of the needs for session
    attributes !

15
Session variables
  • Example

var user null function login() while
(user null) sendPageAndWait("login.html")
user UserRegistry.getUser(
cocoon.request.getParameter("name"),
cocoon.request.getParameter("password") )
function placeOrder() login()
Accounting.placeOrder(user) sendPage("orderPlac
ed.html") function logout() user null
sendPage("bye.html")
Shows the login screenonly if needed
Won't pass through if not logged in !
Just clear user info to log out
16
Managing continuations
  • Continuation trees
  • Browser "back" or "new window"

var cart var user function checkout()
while(user null) cocoon.sendPageAndWait("
login.html") user UserRegistry.getUser(coc
oon.request.get("name"))
cocoon.sendPageAndWait("shippingAddress.html",
who user) var address cocoon.request.get(
"address") cocoon.sendPageAndWait("creditCard.h
tml") var creditCard cocoon.request.get("cre
ditCard") cocoon.sendPageAndWait("confirmOrder.
html") EnterpriseSystem.placeOrder(user,
cart, address, creditCard) cocoon.sendPage("ord
erPlaced.html")

17
Managing continuations
  • Continuation trees
  • Browser "back" the previous path is lost
  • No fear a continuation is lightweight
  • ? Reference to the parent continuation
  • ? Local variables since the parent continuation
  • Browser "new window"
  • Creates a new branch
  • ? Allows "what if ?" navigation in the application

18
Managing continuations
  • Expiring continuations
  • Manual expiration
  • sendPageAndWait() returns its continuation
  • k.invalidate() invalidates the continuation and
    its subtree
  • ? Again, avoids complicated state management
  • Automatic expiration
  • An inactive continuation expires after a delay

var k sendPageAndWait("start.html") ... Busines
sService.commit() // Cannot go back
again k.invalidate()
19
Conclusion
  • Flow script
  • Gives control back to the server
  • ? We always know "where" the browser is
  • Allows sophisticated flow screens
  • ? No need for state automata
  • Increases security and robustness
  • ? Forbids direct access to form submission URLs
  • ? Handles "back" and "new window"

20

Questions ? Answers ! (next Woody)
21
Woody intro
  • The need for form handling
  • Cocoon started as a publication framework
  • ? Many pages, limited user feedback
  • ? Content was mostly written "outside"
  • Evolution towards a general-purpose web framework
  • ? Published content has to be managed
  • ? Used for more and more data-centric
    applications
  • ? Need for good form handling features
  • Various attempts before Woody
  • FormValidatorAction, Precept, XMLForm, JXForms

22
Woody principles
  • The big picture

23
Woody principles
  • The form object model
  • Composed of "widgets"
  • Represents "something" that appears in the form
  • Can read, parse and validate itself
  • Can output its XML representation
  • Some widgets are non-terminal
  • ? Support for tables and rows

24
Woody principles
  • Form definition overview

ltwdform xmlnswd"http//apache.org/cocoon/woody/
definition/1.0"gt ltwdfield id"name"
required"true"gt ltwdlabelgtNamelt/wdlabelgt
ltwddatatype base"string"gt
ltwdvalidationgt ltwdlength min"2"/gt
lt/wdvalidationgt lt/wddatatypegt
lt/wdfieldgt ltwdfield id"email"
required"true"gt ltwdlabelgtEmail
addresslt/wdlabelgt ltwddatatype
base"string"gt ltwdvalidationgt
ltwdemail/gt lt/wdvalidationgt
lt/wddatatypegt lt/wdfieldgt / lt/wdformgt
25
Woody principles
  • Form template overview
  • Embeds widget references in target markup

lthtml xmlnswt"http//apache.org/cocoon/woody/tem
plate/1.0"gt ltheadgt lttitlegtRegistrationlt/titl
egt lt/headgt ltbodygt lth1gtRegistrationlt/h1gt
ltwtform-template action"registration"
method"POST"gt ltwtwidget-label
id"name"/gt ltwtwidget id"name"/gt
ltbr/gt ltwtwidget-label id"email"/gt
ltwtwidget id"email"/gt ltbr/gt /
ltinput type"submit"/gt lt/wtform-templategt
lt/bodygt lt/htmlgt
26
The form definition file
  • Widgets
  • Available widgets
  • ltwdformgt the main form widget
  • ltwdfieldgt "atomic" input field
  • ltwdbooleanfieldgt boolean input
  • ltwdmutivaluefieldgt multiple selection in a
    list
  • ltwdrepeatergt collection of widgets
  • ltwdoutputgt non-modifiable value
  • ltwdactiongt action button (intra-form)
  • ltwdsubmitgt submit button (exits the form)
  • They're all defined in cocoon.xconf
  • ? Add your own if needed

27
The form definition file
  • The ltwdfieldgt widget
  • Definition overview
  • The label can contain abitrary markup
  • Including i18n references

ltwdfield id"..." required"truefalse"gt
ltwdlabelgt...lt/wdlabelgt ltwddatatype
base"..."gt ... lt/wddatatypegt
ltwdselection-listgt ...
lt/wdselection-listgt lt/wdfieldgt
ltwdlabelgtYour ltbgtnamelt/bgtlt/wdlabelgt
ltwdlabelgt lti18ntext key"name-field-label"/gt lt
/wdlabelgt
28
The form definition file
  • Defining the data type of a field
  • Mandatory "base" type
  • Defines the Java type
  • "string", "long", "decimal", "date", "boolean"
  • ? Pluggable components add your own !
  • Optional conversion and validation

ltwddatatype base"..."gt ltwdconvertorgt
... lt/wdconvertorgt ltwdvalidationgt
... lt/wdvalidationgt lt/wddatatypegt
Parsing and formatting
Validation
29
The form definition file
  • Data type parsing and formatting
  • Each base type has a set of converters
  • ? Pluggable components add your own !
  • Example date's "formatting" converter
  • based on java.text.SimpleDateFormat
  • ? locale-dependent patterns

ltwddatatype base"date"gt ltwdconvertor
type"formatting"gt ltwdpatternsgt
ltwdpatterngtyyyy-MM-ddlt/wdpatterngt
ltwdpattern locale"en"gtMM/dd/yyyylt/wdpatterngt
ltwdpattern locale"fr"gtdd/MM/yyyylt/wdpattern
gt ltwdpattern locale"nl-BE"gtdd/MM/yyyylt/wd
patterngt ltwdpattern locale"de"gtdd.MM.yyyylt
/wdpatterngt lt/wdpatternsgt
lt/wdconvertorgt lt/wddatatypegt
30
The form definition file
  • Data type validation
  • A validation rule checks value validity
  • length, range, regexp, creditcard, assert, email
  • ? Pluggable components add your own !
  • A datatype can have several validation rules

ltwdfield id"email"gt ltwddatatype
base"string"gt ltwdvalidationgt
ltwdemail/gt ltwdlength max'100'gt
ltwdfailmessagegtYour address it too
long!lt/wdfailmessagegt lt/wdlengthgt
lt/wdvalidationgt lt/wddatatypegt lt/wdfieldgt
31
The form definition file
  • Selection lists
  • Provide enumerations to the user
  • List of items having a value, with optional label
  • Selection lists can be external and dynamic

ltwdfield name"OS"gt ltwddatatype
base"string"/gt ltwdselection-listgt
ltwditem value"Linux"/gt ltwditem
value"Windows"/gt ltwditem value"Mac OS"/gt
ltwditem value"Solaris"/gt ltwditem
value"other"gt ltwdlabelgtlti18ntext
key"other"/gtlt/wdlabelgt lt/wditemgt
lt/wdselection-listgt lt/wdfieldgt
ltwdselection-list src"cocoon/build-list.xml"gt
32
The form definition file
  • The ltwdrepeatergt widget
  • Repeats a number of child widgets
  • ? Used to manage collections, tables, etc.
  • Specialized ltrepeater-actiongt widgets
  • ? Automatic row addition/deletion

ltwdrepeater id"contacts"gt ltwdfield
id"firstname"gt ltwdlabelgtFirstnamelt/wdlabelgt
ltwddatatype base"string"/gt lt/wdfieldgt
ltwdfield id"lastname"gt ltwdlabelgtLastnamelt/
wdlabelgt ltwddatatype base"string"/gt
lt/wdfieldgt lt/wdrepeatergt
33
The form template
  • The big picture (again)

34
The form template
  • Role of the WoodyTransformer

lthtml xmlnswt"http//apache.org/cocoon/woody/tem
plate/1.0"gt ltheadgt lttitlegtRegistration
formlt/titlegt lt/headgt ltbodygt
lth1gtRegistrationlt/h1gt ltwtform-template
action"registration" method"POST"gt
ltwtwidget-label id"name"/gt ltwtwidget
id"name"/gt ltbr/gt ltwtwidget-label
id"email"/gt ltwtwidget id"email"/gt
ltbr/gt / ltinput type"submit"/gt
lt/wtform-templategt lt/bodygt lt/htmlgt
lthtml xmlnswt"http//apache.org/cocoon/woody/ins
tance/1.0"gt ltheadgt lttitlegtRegistration
formlt/titlegt lt/headgt ltbodygt
lth1gtRegistrationlt/h1gt ltwiform-template
action"registration" method"POST"gt Name
ltwifield id"name"gt
ltwilabelgtNamelt/wilabelgt
ltwivaluegtCocoonlt/wivaluegt lt/wifieldgt
ltbr/gt Email address ltwiwidget
id"email"gt ltwilabelgtEmail
addresslt/wilabelgt ltwivaluegtfoolt/wivalu
egt ltwivalidation-messagegt
Invalid email address lt/wivalidation-mess
agegt lt/wiwidgetgt ltbr/gt /
ltinput type"submit"/gt lt/wiform-templategt
lt/bodygt lt/htmlgt
Expanded widget
Expanded widgets
Validation failed
35
The form template
  • Role of the WoodyTransformer
  • Expand all "wt" elements in their "wi"
    counterpart
  • ? "wt" Woody template
  • ? "wi" Woody instance
  • Output of the transformer goes to styling
  • Provided HTML styling
  • Other stylings are possible (e.g. WML)
  • ? Woody does not hardcode the presentation !

36
The form template
  • The ltwtwidgetgt element
  • Produces the corresponding widget instance
  • Markup depends on the actual widget
  • For fields ltwilabelgt, ltwivaluegt,
    ltwiselection-listgt
  • ltwtwidgetgt can contain styling information
  • Drives the styling stylesheet
  • ? Contents of ltwistylinggt depends on the
    stylesheet !

ltwtwidget id"fourchars"gt ltwistyling
list-type"listbox"
listbox-size"4"/gt lt/wtwidgetgt
ltwtwidget id"fourchars"gt ltwistyling
list-type"radio"/gt lt/wtwidgetgt
37
The form template
lttablegt lttrgt ltthgtNamelt/thgt ltthgtEmail
addresslt/thgt lt/trgt lttrgt lttdgt
ltwifield id"contacts.0.firstname"gt
ltwilabelgtNamelt/wilabelgt
ltwivaluegtHarrylt/wivaluegt lt/wifieldgt
lt/tdgt lttdgt ltwifield id"contacts.0.emai
l"gt ltwilabelgtEmail addresslt/wilabelgt
ltwivaluegtharry_at_potter.comlt/wivaluegt
lt/wifieldgt lt/tdgt lt/trgt lttrgt lttdgt
ltwifield id"contacts.1.firstname"gt
ltwilabelgtNamelt/wilabelgt
ltwivaluegtAnakinlt/wivaluegt lt/wifieldgt
lt/tdgt lttdgt ltwifield id"contacts.1.emai
l"gt ltwilabelgtEmail addresslt/wilabelgt
ltwivaluegtanakin_at_skywalker.comlt/wivaluegt
lt/wifieldgt lt/tdgt lt/trgt lt/tablegt
  • The ltwtrepeater-widgetgt element
  • Iterates on the contents of a ltwdrepeatergt

lttablegt lttrgt ltthgt ltwtrepeater-widget-
label id"contacts" widget-id"firstname
"/gt lt/thgt ltthgt ltwtrepeater-widget-l
abel id"contacts" widget-id"email"/gt
lt/thgt lt/trgt ltwtrepeater-widget
id"contacts"gt lttrgt lttdgt
ltwtwidget id"firstname"/gt lt/tdgt
lttdgt ltwtwidget id"email"/gt lt/tdgt
lt/trgt lt/wtrepeater-widgetgt lt/tablegt
38
Built in HTML styling
  • Field styling
  • Basic styling html input
  • ltwistyling type""gt
  • "password", "hidden", "textarea", "date"
  • "listbox", "radio" for selection-lists

39
Built in HTML styling
  • ltwigroupgt styling
  • Instance-only widget providing high-level styling
  • ? No corresponding ltwdgt nor ltwtgt

type"fieldset"
ltwigroupgt ltwilabelgtProfile headerlt/wilabelgt
ltwistyling type"fieldset" layout"columns"/gt
ltwiitemsgt ltwtwidget id"revision"/gt
ltwtwidget id"identification"/gt ltwtwidget
id"name"/gt ltwtwidget id"author"/gt
ltwtwidget id"classID"/gt ltwtwidget
id"releaseDate"gt ltwistyling
type"date"/gt lt/wtwidgetgt
lt/wiitemsgt lt/wigroupgt
layout"columns"
40
Built in HTML styling
  • ltwigroupgt styling
  • Container rendering
  • ? "type" attribute "fieldset", "tabs", "choice"
  • ? Tabs defined with CSS

type"choice"
type"tabs"
41
Interactive forms
  • Server-side event handler,client-side trigger

ltwdfield id"make" required"true"gt
ltwdlabelgtMakelt/wdlabelgt ltwddatatype
base"string"/gt ltwdselection-list
src"cocoon/cars" dynamic"true"/gt
ltwdon-value-changedgt ltjavascriptgt var
value event.newValue var type
event.source.parent.getWidget("type") if
(value null) type.setSelectionList(ne
w EmptySelectionList("Select a maker
first")) else
type.setSelectionList("cocoon/cars/"value)
typewidget.setValue(null)
lt/javascriptgt lt/wdon-value-changedgt lt/wdfieldgt
ltwtwidget id"make"gt ltwistyling
submit-on-change"true"/gt lt/wtwidgetgt
Change the type selection list
42
Linking forms to application data
  • An additional binding definition file
  • Associates widget names to XPath expressions on
    the data model
  • Example binding to an XML document

ltwbcontext xmlnswb"http//apache.org/cocoon/
woody/binding/1.0" xmlnswd"http//apache.org/
cocoon/woody/definition/1.0" path"user" gt
ltwbvalue id"email" path"email"
readonly"true"/gt ltwbvalue id"number"
path"number/_at_value"gt ltwdconvertor
datatype"long"/gt lt/wbvaluegt ltwbvalue
id"choose" path"choose/_at_value"gt
ltwdconvertor datatype"boolean"/gt
lt/wbvaluegt lt/wbcontextgt
Set the context of included paths
Read-only widget
Associates a widget to a path
Binding convertor (XML is text)
43
Putting it all together
  • The woody.js library
  • Provides a Form class
  • Constructor takes a form definition file
  • Method Form.showForm() to display the form
  • Returns when validation ok or non-validating
    submit
  • ? Internal loop on sendPageAndWait()

function edit_header() var data
Application.getData() var form new
Form("forms/profile-header-def.xml")
form.createBinding("forms/profile-header-binding.x
ml") form.load(data) form.showForm("view-pr
ofile-header.html", foo bar) if
(form.submitId "ok") form.save(data)
sendDialog("Thanks a lot") else
sendDialog("Bye bye")
Loadapp. data
Show form and wait
Test submit button
Saveapp. data
44
Putting it all together
  • The sitemap

Selection by http method form's action is ""
(same URL)
ltmapmatch pattern"edit-.html"gt ltmapselect
type"method"gt lt!-- GET start the flow for
this screen --gt ltmapwhen test"GET"gt
ltmapcall function"editor_1"/gt
lt/mapwhengt lt!-- POST (form submission)
continue the flow --gt ltmapwhen test"POST"gt
ltmapcall continuation"request-paramcontin
uation-id"/gt lt/mapwhengt
lt/mapselectgt lt/mapmatchgt ltmapmatch
pattern"view-.html"gt ltmapgenerate
type"jxtemplate" src"forms/1-tmpl.xml"/gt
ltmaptransform type"woody"/gt ltmaptransform
type"i18n"/gt ltmaptransform type"xslt"
src"resources/editor-styling.xsl"/gt
ltmapserialize type"html"/gt lt/mapmatchgt
"editor_" prefix restricts access to flowscript
functions
JXTemplate to use showForm's context data
45
Conclusion
  • A powerful form framework
  • Rich datatypes and validation rules
  • Easy extension to specific needs
  • Event handling for sophisticated interaction
  • Fancy builtin stylesheets
  • Easy to use with flowscript
  • A community development
  • Initiated by Outerthought
  • Welcomes additions and contributions
  • ? Woody will be the form framework for Cocoon

See also http//wiki.cocoondev.org/Wiki.jsp?pageW
oody
46

Questions ? Answers !
Write a Comment
User Comments (0)
About PowerShow.com