Download as pdf
Download as pdf
You are on page 1of 37

Bejug Web Workshop

The
Power Trio
“Serious webapps can still be fun!”

Steven Noels
Managing Partner
Outerthought
What you will learn

 Cocoon is not just an XML web


publishing platform
 Serious webapps can still be fun
 Write code only when you need to

2
About myself

 Managing Partner of Outerthought: technology


mentoring of open source Java & XML
development
 Member of the Apache Software Foundation

 Three kids, one wife

 Ongoing rants at
http://blogs.cocoondev.org/stevenn/

3
“We don’t spend nearly enough
time on TSS.”

4
Agenda

 Introducing Cocoon
 The Cocoon Sitemap
 The magical trio: pipelines, flow and forms
 Web continuations using Flowscripts
 Cocoon Forms aka Woody
 Binding to XML, beans and back-ends
 Apache Cocoon: where and what

5
The big picture

6
Introducing Cocoon

 Java Web application development framework


 http://cocoon.apache.org/
 SAX Pipelines & central declarative configuration
 Separation of Concerns
 Not a petty framework, comes with a footprint
 Made for larger projects & teams
 Focus on composability rather than programmability
 “We figure out the hard parts, you get to do the fun stuff.”
 Core + Blocks
 Core = pipelines, sitemap, flow, woody forms, i18n, jxtemplate
 Blocks: portal, fop, axis, poi, batik, databases, authentication, SAP
web3, W ebDAV …
 Built-time application assembly configuration
 Hot-deployment and -reconfiguration is planned 7
Cocoon highlights

 Builds on Apache Avalon foundations


 pooling, configuration, lifecycle management
 Tackles state management with continuations
rather than FSM controllers
 Comes with a full-blown portal engine
 Didn’t I say we spent way too little time on TSS? 
 Can provide JSR-168 Portlets, W -I-P on container
 Related projects & tools
 Database reporting: xReporter - http://xreporter.cocoondev.org/
 Content management
 Lenya CMSystem - http://cocoon.apache.org/lenya/
 Daisy CMFramework - stay tuned for summer 2004
 SunBow: Eclipse Cocoon plugin
 Pollo: XML & Cocoon sitemap editor 8
The Cocoon Sitemap

9
The Cocoon Sitemap

 XML description of the URI Namespace of your


webapp
 Matchers select a Pipeline depending on request
context
 Pipeline consists of:
 Generator
 Generates XML (SAX) events to be passed into the Pipeline
 One or more Transformers
 Act on incoming SAX events
 Serializer
 Sink SAX stream into ByteStream for network transport

 Other components: Selectors, Readers, Actions,


Views, Error Handlers
10
HelloWorld.xmap

<map:match pattern="*.html">
<map:generate src=”xdocs/{1}.xml"/>
<map:transform src=“style/xdocs2html.xsl”/>
<map:serialize/>
</map:match>

11
More sitemap niftiness

<map:match pattern="*-display-pipeline">
<map:generate src="forms/{1}_template.xml"/>
<map:transform type="woody"/>
<map:transform type="i18n">
<map:parameter name="locale" value="en-US"/>
</map:transform>
<map:call resource="simple-page2html">
<map:parameter name="file" value="forms/{1}_template.xml"/>
</map:call>
<map:transform src="resources/woody-samples-styling.xsl"/>
<map:serialize/>
</map:match>

<map:resource name="simple-page2html">
<map:transform
src="context://samples/common/style/xsl/html/simple-
page2html.xsl">
<map:parameter name="file" value="{file}"/>
</map:transform>
</map:resource>

12
Snippet explanation

 This Matcher will be triggered by a URI ending with foo-


(internal or external)
display-pipeline
 It will Generate pipeline input by reading an XML file
from disk: forms/foo_template.xml
 It is passed through the Woody and i18n Transformer
 A reusable pipeline fragment (resource) is call-ed: simple-
page2html
 And a final Transformation before the Serialization
happens
 Defaults (configurable): File Generator, XSLT/TRAX
Transformation, HTML Serialization

13
Pipeline components

Non-exhaustive list (not the purpose of this


talk)

Passive Active
Generators Matchers
file, http, chaperon, request, directory, wildcard URI, regexp URI, request &
XSP, stream, JSP session parameter

Transformers Selectors
TRAX, i18n, nInclude, SourceWriting, browser (UA), host, sitemap, request &
LDAP, SQL session parameter

Serializers Actions
(X)HTML, SVG, PNG, text, ZIP, PDF, authentication, database, mail, session,
Excel
form

Input Modules
(accessing various input parameters in
the sitemap)
14
Introducing the Magical Trio

 Model I (Pure JSP, PHP, ASP)

 Concerns are mixed


 Only for view-driven applications (publishing)
 Ouch, this hurts!
15
Introducing the Magical Trio

 Model II (Struts and many others)

 Let’s try and map this better onto Cocoon …


16
Cocoon “MVC”

17
Web Continuations and Flowscripts

 Classic Controller: state management and


dispatching (FSM)
 FlowScript does more:
 Calls business layer, chooses view
 Linear, program-like description of program execution flow
 On-the-fly state management through Continuations
 JavaScript?!
 Runs inside Rhino, a Java JS engine (Mozilla)
 Interpreted  fast roundtrips
 Support for Continuations (aka saving the stack)
 Other (future) possibilities: Groovy, Brakes (Java)
 Has access to Java context (Flow object model)
 Can instantiate Java classes - automagically wrapped
 Familiar yet simpler syntax
18
FlowScript Example

var email;

function newsletter()
creates a continuation {
+ invokes view while(email == null) {
+ “suspends” script cocoon.sendPageAndWait("email-form");

upon submit, email = cocoon.request.get("email"));


execution will resume here
if (!checkEmail(email))
email = null;
invokes view, }
script will exit cocoon.sendPage("registered", {who: email});

pipelines view context

19
Continuations

 Contain
 Function call stack
 Local variables values
 Unique ID
 Can be manually invalidated, or via automated
cleanup (expiration)
 Support “branching” (back button, clone browser
window)

20
Business Layer: it is up to you!

 Use FlowScript all-the-way (bad!)


 Use some O/R mapping (OJB, Hibernate) from
inside FlowScript (slightly better)
 FlowScript + Java facade, providing access to
BO and methods on back-end
 POJO/JavaBeans ( EJB)
 Persistency framework (OJB, Hibernate)
 “ReST” or “W ebServices” (i.e. HTTP & XML)
 Axis
 XMLBeans & httpclient
 W rap back-end business use cases into a front-end page flow
use case
 (opt.) Avalon (configuration, monitoring, logging)

21
Model, Controller, … View

 JXTemplate Generator/Transformer
 XML Templates interspersed with JXPath/Jexl object value
lookups
 No code allowed (compared to JSP/XSP)
sendPage("checkout.html",
{"customer": user, "cart": cart});

<p>Welcome, #{customer/firstName}</p>

 A few control structures:


Your cart:
<ul>
<jx:forEach var="item" items="${cart.items}">
<li>${item.quantity} ${item.name}</li>
</jx:forEach>
</ul>
<a href="kont/${continuation.id}">Continue</a>

22
Bringing it all together

23
Cocoon Forms aka Woody

 Official Cocoon Form framework “CForms”


 Adopted in favor of XMLForms and JXForms
 Hand-rolled form handling still possible using various Actions
 Fundamentals
 Very little Java coding required
 Strong datatyping & type conversion capabilities
 Offers a growing set of ready-made widgets
 Integrates with various development styles (flow, actions)
 Inspired and improved upon JSF
 Server-side form model
 Event model
 Process/request lifecycle
 No Controller enforced by the form framework
 No RenderKits, we use simple XSLT instead
 Better SoC
 Binds to JavaBeans and more 24
Overview

25
Demo registration form

26
Form Definition
<?xml version="1.0" encoding="ISO-8859-1"?> <wd:label>Password:</wd:label>
<wd:form <wd:datatype base="string">
xmlns:wd="http://apache.org/cocoon/woody/definition/1.0" <wd:validation>
xmlns:i18n="http://apache.org/cocoon/i18n/2.1"> <wd:length min="5" max="20"/>
<wd:widgets> </wd:validation>
<wd:field id="name" required="true"> </wd:datatype>
<wd:label>Name:</wd:label> </wd:field>
<wd:field id="confirmPassword" required="true">
<wd:datatype base="string">
<wd:label>Re-enter password:</wd:label>
<wd:validation>
<wd:datatype base="string">
<wd:length min="2"/>
<wd:validation>
</wd:validation>
<wd:assert test="password = confirmPassword">
</wd:datatype>
<wd:failmessage>The two passwords are not
</wd:field> equal.</wd:failmessage>
<wd:field id="email" required="true"> </wd:assert>
<wd:label>Email address:</wd:label> </wd:validation>
<wd:datatype base="string"> </wd:datatype>
<wd:validation> </wd:field>
<wd:email/> ...
</wd:validation>
</wd:datatype>
</wd:field>
<wd:field id="age">
<wd:label>Your age:</wd:label>
<wd:datatype base="long">
<wd:validation>
<wd:range min="0" max="150"/>
</wd:validation>
</wd:datatype>
</wd:field>
<wd:field id="password" required="true">
27
Available Widgets

 Field widget
<wd:field id="..." required="true|false">
<wd:label>...</wd:label>
<wd:hint>...</wd:hint>
<wd:help>...</wd:help>
<wd:datatype base="...">
[...]
</wd:datatype>
<wd:selection-list .../>
<wd:on-value-changed>
...
</wd:on-value-changed>
</wd:field>

 Datatypes: string, decimal, integer, long, date, enum


 Selection lists: retrieve possible values from external
resources 28
Available Widgets

 multivaluefield  upload
 booleanfield  HTMLArea
 repeater

 output (read-only
field)
 action (events)
 submit
 aggregatefield 29
Form Template
<?xml version="1.0"?>
<page xmlns:wt="http://apache.org/cocoon/woody/template/1.0"
xmlns:wi="http://apache.org/cocoon/woody/instance/1.0">
<title>Registration</title>
<content>
<wt:form-template action="#{$continuation/id}.continue" method="POST">
<wt:widget-label id="name"/>
<wt:widget id="name"/>
<br/>
<wt:widget-label id="email"/>
<wt:widget id="email"/>
<br/>
<wt:widget-label id="age"/>
<wt:widget id="age"/>
<br/>
<wt:widget-label id="password"/>
<wt:widget id="password">
<wi:styling type="password"/>
</wt:widget>
<br/>
<wt:widget-label id="confirmPassword"/>
<wt:widget id="confirmPassword">
<wi:styling type="password"/>
</wt:widget>
<br/>
<wt:widget id="spam"/>
<wt:widget-label id="spam"/>
<br/>
<input type="submit"/>
</wt:form-template>
</content> 30
</page>
Rendering a form

 WoodyTemplateTransformer + XSLT

31
Binding to XML, beans and back-ends

32
Demo XML Binding

33
Binding sample
public class Form2Bean {
 Based on JXPath
private String email;
private String ipAddress;  XML
public String getEmail() {  JavaBeans
return email;
}  Directional binding
public void setEmail(String email) {  load
this.email = email;
}  save
public String getIpAddress() {
return ipAddress;  repeater support
}
 Possibility to write
public void setIpAddress(String ipAddress) {

}
this.ipAddress = ipAddress; binding code in
} JavaScript

Binding definition file


<wb:context xmlns:wb="http://apache.org/cocoon/woody/binding/1.0" path="/" >

<wb:value id="email" path="email" direction="load"/>


<wb:value id="ipaddress" path="ipAddress"/>
... 34
The Apache Cocoon Project

 http://cocoon.apache.org/
 Mailing list pop stats: on par with Ant
users list population (2004-2-24)

3000

2500

2000

1500

1000

500

axis ant fop poi slide


strutstomcat httpd soap
cocoon lucene
xerces-j xindic evelocityturbine xalan-j
jetspeed tapestry

spamassassin jakarta taglibs


35
jakarta c ommons
The Apache Cocoon Project

 40-ish committers, > 80% European


 Annual Cocoon GetTogether
developers list population (2004-2-24)

900

800

700

600

500

400

300

200

100

fop ant slide


httpd struts soap
tomcat cocoon lucene xalan xindicexerces-j forrestvelocity
geronimo xerces-c jetspeed

jakarta taglibs 36
jakarta commons
Conclusions

 Barely scratched the surface 


 Good for team development through SoC
 Code only when you have to
 Business-friendly open source license

 http://cocoon.apache.org/
 European-wide business support by Orixo - the
XML Business Alliance

Thank you!
37

You might also like