Вы находитесь на странице: 1из 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

Вам также может понравиться