SlideShare une entreprise Scribd logo
1  sur  143
Télécharger pour lire hors ligne
Apache Wicket

10 years and beyond
Martijn Dashorst

topicus onderwijs
@dashorst
APACHE WICKET
a brief history

of Wicket
the current state

of Wicket
the future

of Wicket
co-author
10 year contributor to Wicket
started in 2004 at topicus
without any knowledge of web programming
before Wicket
at topicus
2004
using maverick velocity
hibernate jasperreports
lots of XML configuration
1 change requires N files to be
modified
(for large values of N)
<command name="admin.tabelbeheer.edittoetsonderdeel">

<controller class="nl.topicus.bao.web.ctrl.lab.toetsen.

<view name="success" path="/admin/tabelbeheer/toetsen/e

<transform path="/mlayout/mainlayout.vm">

<param name="_pagetitle" value="Beheer Tabellen

</transform>

</view>

<view name="error" path="/admin/tabelbeheer/toetsen/edi

<transform path="/mlayout/mainlayout.vm">

<param name="_pagetitle" value="Beheer Tabellen

</transform>

</view>

<view name="list" path="admin.tabelbeheer.edittoets.m" 

</command>
high learning curve
no back button support
no multi-tab support
HTTP Session dumping
ground
little to no reuse
</tr>

#if($model.bean.absentieRegels.empty)

<tr>

<td colspan="19" class="border-r">#formname('groep.absent'

</tr>

#else

#set($columnIndexes=[1,2,3,4,5,6,7,8,9,10])

#foreach($row in $model.bean.absentieRegels)

<tr>

<td class="columnvalue">$arrayTool.elementAt($row, 0)</td

#foreach($index in $columnIndexes)

#set($melding=$arrayTool.elementAt($row, $index))
complex UI neigh impossible
a framework that makes
reuse possible, minimises
configuration, server side
state management easy
and is as type safe as
possible
Action Framework Anvil Apache Click Apache MyFaces Apache
Shale Apache Sling Apache Struts Apache Struts 2 Apache
Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web
Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill
Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis
Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower
framework Folium FormEngine Genie Grails GWT Hamlets Helma
Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss
Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay
jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw
Makumba Maverick Melati Mentawai Millstone Nacho Niggle
OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora
Playframework Pustefix Restlet RIFE Roma Meta Framework RSF
Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC
Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire
Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare
Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze
Framework ZK ztemplates
120+ java web frameworks
18 August 2004
public class EditPage extends WebPage {

private Person person;



public EditPage(Person person) {

this.person = person;



add(new Button("save") {

@Override

public void onSubmit() {

Entities.save(person);

setResponsePage(new ShowPage(person));

}

});

}

}
a framework that makes
reuse possible, minimises
configuration, server side
state management easy
and is as type safe as
possible
✓ ✓
✓
✓
Action Framework Anvil Apache Click Apache MyFaces Apache
Shale Apache Sling Apache Struts Apache Struts 2 Apache
Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web
Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill
Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis
Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower
framework Folium FormEngine Genie Grails GWT Hamlets Helma
Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss
Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay
jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw
Makumba Maverick Melati Mentawai Millstone Nacho Niggle
OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora
Playframework Pustefix Restlet RIFE Roma Meta Framework RSF
Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC
Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire
Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare
Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze
Framework ZK ztemplates
Action Framework Anvil Apache Click Apache MyFaces Apache
Shale Apache Sling Apache Struts Apache Struts 2 Apache
Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web
Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill
Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis
Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower
framework Folium FormEngine Genie Grails GWT Hamlets Helma
Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss
Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay
jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw
Makumba Maverick Melati Mentawai Millstone Nacho Niggle
OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora
Playframework Pustefix Restlet RIFE Roma Meta Framework RSF
Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC
Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire
Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare
Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze
Framework ZK ztemplates
15 java web frameworks alive
i.e. made any release in the last year
including Wicket!
What is Wicket?
Apache Wicket
From Wikipedia, the free encyclopedia
Apache Wicket, commonly referred to as
Wicket, is a lightweight component-based web
application framework for the Java programming
language conceptually similar to JavaServer
Faces and Tapestry. It was originally written by
Jonathan Locke in April 2004. Version 1.0 was
released in June 2005. It graduated into an
Apache top-level project in June 2007.[2]
A brief history of
Wicket
2004
2004
The Server Side
20052004
codehaus.org
The Server Side
20052004
codehaus.org
The Server Side
codehaus.org
2004
The Server Side JavaOne
1.0
1.1
2006
1.2
2005
AJAX
2007
2007
1.3
2008
2007
1.3
2008 2009
1.4
2010 2011
1.5
2007
1.3
2008 2009
1.4
2010 2011
1.5
2012
6.0
2013 2014
6.12
6.2
6.4
6.6
6.8
6.10
6.1 6.5 6.9
6.11
6.13
7.0.0-M2
6.16
6.14
6.15
7.0.0-M1
6.3 6.7
6.17
7.0.0-M3
7.0.0-M4
6.18
That's
of Apache Wicket!
10 years
The state of
Wicket
1. core
2. extensions
3. spring
4. datetime
5. auth-roles
Mailinglist traffic
Commit activity
Meanwhile
at devoxx...
0%
25%
50%
75%
100%
REST+JavaScript
SpringMVC
JavaScriptlibrary
JSF+JavaEE
GWT
Wicket
Play
Vaadin
Strutsv1orv2
Grails
ApacheSling
WebSockets+JavaScript
Spray+AkkaHTTP
ZKframework
Other
User Manual
195
25 Wicket Internals
25.1 Page storing
During request handling, Wicket manages page instances through interface
. This interface creates a new page instance ororg.apache.wicket.request.handler.IPageProvider
loads a previously serialized page instance if we provide the corrisponding page id. delegatesIPageProvider
page creation and retrieval to interface . When pageorg.apache.wicket.request.mapper.IPageSource
class is provided delegates page creation to interface ,IPageSource org.apache.wicket.IPageFactory
while when page id is provided it uses interface to load theorg.apache.wicket.page.IPageManager
previously serialized page.
The following workflow diagram summarizes the mechanism seen so far:
IPageManager
's task is to manage which pages have been used in a requestorg.apache.wicket.page.IPageManager
and store their last state in the backing stores, namely . The default implementationIPageStore
collects all stateful pages which have been used in theorg.apache.wicket.page.PageStoreManager
request cycle (more than one page can be used in a single request if for example orsetResponsePage()
is used). At the end of the request all collected page instances are being storedRestartResponseException
in the first level cache - http session. They are stored in http session attribute named
and passed to the underlying"wicket:persistentPageManagerData-APPLICATION_NAME" IPageStore
. When the next http request comes will ask for page with specific id andIPageProvider PageStoreManager
will look first in the http session and if no match is found then it will delegate to the IPageStore. At the end of the
second request the http session based cache is being overwritten completely with the newly used page
instances.
To setup another implementation useIPageManager
. Theorg.apache.wicket.Application.setPageManagerProvider(IPageManagerProvider)
custom implementation may or may not use .IPageManager IPageStore/IDataStore
IPageStore
's role is to mediate the storing and loading of pages done byorg.apache.wicket.pageStore.IPageStore
the underlying . The default implementationIDataStore
pre-processes the pages before passing them toorg.apache.wicket.pageStore.DefaultPageStore
183
As you can see above, the Exception gets raised during the initialization of the instance evenWicketTester
before the actual test method gets executed. Even though we have applied rather cool and simple annotation
based test configuration already described and passed in perfectly well prepared ApplicationContext instance to
the WicketTester instance in the constructor, somewhere down the rabbit hole someone complained that no
WebApplicationContext instance could have been found which seems to be required in order to initialize the
WicketTester properly.
The problem that we run against here is due to the fact that SpringComponentInjector during its own initialization
is trying to get hold of an according Spring's ApplicationContext instance that would normally be there in a
runtime environment but does not find any since we are running in a test environment currently.
SpringComponentInjector delegates to Spring's own WebApplicationContextUtils class to retrieve the instance of
ApplicationContext out of the ServletContext which is perfectly fine for a runtime environment but is unfortunately
failing in a test environment:
public WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)static
IllegalStateException {throws
WebApplicationContext wac = getWebApplicationContext(sc);
(wac == ) {if null
IllegalStateException(throw new "No WebApplicationContext found: no
);ContextLoaderListener registered?"
}
wac;return
}
If you still remember we defined a ContextLoaderListener in our web.xml file as part of the configuration of our
runtime environment that makes sure an according WebApplicationContext instance gets initialized and
registered against the ServletContext properly. Luckily, this problem can easily be solved if we slightly change
the way we initialize SpringComponentInjector in our main MyWebApplication class. Apart from the constructor
that we have used so far, there is another constructor in the SpringComponentInjector class that expects the
caller to provide it with an according ApplicationContext instance rather than trying to resolve one on its own:
public SpringComponentInjector(WebApplication webapp, ApplicationContext ctx,
wrapInProxies)boolean
{
(webapp == )if null
{
IllegalArgumentException( );throw new "Argument [[webapp]] cannot be "null
}
(ctx == )if null
{
IllegalArgumentException( );throw new "Argument [[ctx]] cannot be "null
}
// store context in application's metadata …
webapp.setMetaData(CONTEXT_KEY, ApplicationContextHolder(ctx));new
// … and create and register the annotation aware injector
InjectorHolder.setInjector( AnnotSpringInjector( ContextLocator(),new new
In a Nutshell, Wicket...
… has had 18,255 commits made by 62 contributors
representing 318,037 lines of code
… is mostly written in Java with

a well-commented source code
… has a well established, mature codebase maintained
by a large development team with stable Y-O-Y
commits
… took an estimated 84 years of effort (COCOMO model)

starting with its first commit in September, 2004

ending with its most recent commit 1 days ago
– openhub.net report for Wicket
The future of
Wicket
?
Wicket 1.4
security releases only
Wicket 1.5
security releases only
Wicket 6
java 6
semantic
versioning
semi-monthly releases
mainly bug fixes
some new minor features
Wicket 7
Java 7
Servlet 3
Minor API breaks
Component queuing
public class HomePage extends WebPage {
public HomePage() {
add(new Label("title", "Hello!"));
}
}
public class HomePage extends WebPage {
public HomePage() {
add(new Label("title", "Hello!"));
}
} <html>
<body>
<h1 wicket:id="title"></h1>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
add(new Label("title", "Hello!"));
}
} <html>
<body>
<h1 wicket:id="title"></h1>
</body>
</html>
Add a <div> around content...
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {public HomePage() {
add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {public HomePage() {
add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));}
}
code always follows markup
in Wicket
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
WebMarkupContainer container =
new WebMarkupContainer("container");
add(container);
add(new Label("title", "Hello!"));
}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
WebMarkupContainer container =
new WebMarkupContainer("container");
add(container);
add(new Label("title", "Hello!"));
}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
WebMarkupContainer container =
new WebMarkupContainer("container");
add(container);
container.add(new Label("title", "Hello!"));
}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
code always follows markup
in Wicket
or does it?
Enter Component Queuing
(coming to you in wicket 7)
What if we delay adding
components?
Queue components until their location
in the markup hierarchy is know
markupContainer.add(new Label(...));
markupContainer.queue(new Label(...));
public class HomePage extends WebPage {

public HomePage() {

WebMarkupContainer container = 

new WebMarkupContainer("container");

add(container);

container.add(new Label("title", "Hello!"));

}

}
public class HomePage extends WebPage {

public HomePage() {

queue(new WebMarkupContainer("container"));

queue(new Label("title", "Hello!"));

}

}
<html>
<body>
<header><h1 wicket:id="title"></h1></header>
<div wicket:id="container">
...
</div>
</body>
</html>
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
Limitations of

Component Queuing
queue(new Label("label", "Some text"));

queue(new Label("label", "Other text"));
queue(new Label("label", "Some text"));

queue(new Label("label", "Other text"));
queue(new Label("first"));

queue(new Label("last"));



WebMarkupContainer secure=new
WebMarkupContainer("secure") {

public void onConfigure() {

super.onConfigure();

setVisible(isViewingOwnProfile());

}

};



queue(secure);

secure.queue(new Label("creditCardNumber"));

secure.queue(new Label("creditCardExpiry"));
Restrictions of Queuing: Ancestors
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

</fieldset>
<dt>Card number: <i wicket:id="creditCardNumber">
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

</fieldset>
<dt>Card number: <i wicket:id="creditCardNumber">
<fieldset wicket:id="secure">

<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
<fieldset wicket:id="secure">

<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
Component Queuing
• Wicket 7 feature
• Prefer queue() when markup hierarchy can be altered
• Uniqueness of Wicket IDs still requirement at same
level of queuing
• Can move down into child markup hierarchy
• Can't move up the markup hierarchy
Wicket 8
Java 8
PROJECT LAMBDA
“functional” programming in
Java
public interface ILinkListener {

void onLickClicked();

}
ILinkListener l = new ILinkListener(){

@Override

public void onLinkClicked() {

System.out.println("Klik");

}

}
public interface ILinkListener {

void onLickClicked();

}
ILinkListener l = () -> {

System.out.println("Klik");

}
ILinkListener l = () -> {

System.out.println("Klik");

}
ILinkListener l = new ILinkListener(){

@Override

public void onLinkClicked() {

System.out.println("Klik");

}

}
or
add(new Link<Void>("save") {

@Override

public void onClick() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

});
add(new Link<Void>("save") {

@Override

public void onClick() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

});
add(new Link<>("save").onClick(()-> {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

});
no more type
information
private void onSave() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

private void onSave() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

add(new Link<Void>("save")

.onClick(this::onSave));

A link with onclick, visibility and
body
add(new Link<Void>("like"));



add(new Link<Void>("like") {

});
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}

});
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

});
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody());
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

}));
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

@Override

public String getObject() {

}
}));
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

@Override

public String getObject() {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

}
}));
A link with onclick, visibility and
body
add(new Link<>("like"));

add(new Link<>("like")

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

.body(() -> {

})

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

.body(() -> {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

})

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

.body(() -> {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

})

);

add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

@Override

public String getObject() {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

}
}));
Anon inner classes: 17 lines
Java 8 lambdas: 9 lines
nashorn
JavaScript validation
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
Object result = nashorn.eval(js);
try {
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
try {
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch (Exception e) {
}
java.time
Schedule
6.14
6.15
7.0-M1
7.0-M2
7.0-M4
6.18
feb mar nov
2014
7.0-RC
6.19
jan
7.0?
7.1?
8.0-M1?
7.5?
feb mar may
2015
8.0-M2?
7.6?
jun
Is there a future for 

server-side frameworks?
0%
25%
50%
75%
100%
REST+JavaScript
SpringMVC
JavaScriptlibrary
JSF+JavaEE
GWT
Wicket
Play
Vaadin
Strutsv1orv2
Grails
ApacheSling
WebSockets+JavaScript
Spray+AkkaHTTP
ZKframework
Other
JavaScript Frameworks War
JQuery AngularJS Ember.js React
Backbone.js Meteor KnockoutJS Dojo
Agility.js CanJS Polymer Mithril
Maria Flight Knockback.jsAmpersand
What is the Future for web
development?
What is the Future for web
development?
Web Components
What is the Future for web
development?
Web Components
PolymerAngularJS
(2.0)
What is the Future of Wicket?
No Revolution but Evolution
a brief history

of Wicket
the current state

of Wicket
the future

of Wicket
Summary
thank you
Questions?
contact
@dashorst
topicus stand

Contenu connexe

Tendances

REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011Shreedhar Ganapathy
 
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Mihail Stoynov
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSArun Gupta
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3Zachary Klein
 
Better Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian PluginsBetter Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian PluginsWojciech Seliga
 
Microservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudMicroservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudBen Wilcock
 
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataIn The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataStacy London
 
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitAtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitWojciech Seliga
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play appsYevgeniy Brikman
 
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...VMware Tanzu
 
From CakePHP to Laravel
From CakePHP to LaravelFrom CakePHP to Laravel
From CakePHP to LaravelJason McCreary
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action Alex Movila
 

Tendances (20)

REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
 
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RS
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3
 
Better Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian PluginsBetter Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian Plugins
 
Node.js vs Play Framework
Node.js vs Play FrameworkNode.js vs Play Framework
Node.js vs Play Framework
 
Microservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudMicroservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloud
 
Apache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolboxApache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolbox
 
DataFX - JavaOne 2013
DataFX - JavaOne 2013DataFX - JavaOne 2013
DataFX - JavaOne 2013
 
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataIn The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
 
Apache Lucene for Java EE Developers
Apache Lucene for Java EE DevelopersApache Lucene for Java EE Developers
Apache Lucene for Java EE Developers
 
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitAtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
 
Migrating to Java 9 Modules
Migrating to Java 9 ModulesMigrating to Java 9 Modules
Migrating to Java 9 Modules
 
Angular beans
Angular beansAngular beans
Angular beans
 
Coding Your Way to Java 12
Coding Your Way to Java 12Coding Your Way to Java 12
Coding Your Way to Java 12
 
From CakePHP to Laravel
From CakePHP to LaravelFrom CakePHP to Laravel
From CakePHP to Laravel
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
 

En vedette (10)

Wicket In Action - oredev2008
Wicket In Action - oredev2008Wicket In Action - oredev2008
Wicket In Action - oredev2008
 
Développement d'un site web de E-Commerce avec PHP (Première Partie)
Développement d'un site web de E-Commerce avec PHP (Première Partie)Développement d'un site web de E-Commerce avec PHP (Première Partie)
Développement d'un site web de E-Commerce avec PHP (Première Partie)
 
Cours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxyCours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxy
 
Support POO Java première partie
Support POO Java première partieSupport POO Java première partie
Support POO Java première partie
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
 
Support de cours Spring M.youssfi
Support de cours Spring  M.youssfiSupport de cours Spring  M.youssfi
Support de cours Spring M.youssfi
 
Support de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfiSupport de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfi
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
 
Support programmation orientée objet c# .net version f8
Support programmation orientée objet c#  .net version f8Support programmation orientée objet c#  .net version f8
Support programmation orientée objet c# .net version f8
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
 

Similaire à Wicket 10 years and beyond

Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applicationshchen1
 
Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course JavaEE Trainers
 
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)DK Lee
 
Web container and Apache Tomcat
Web container and Apache TomcatWeb container and Apache Tomcat
Web container and Apache TomcatAuwal Amshi
 
Knowledge Sharing : Java Servlet
Knowledge Sharing : Java ServletKnowledge Sharing : Java Servlet
Knowledge Sharing : Java ServletFahmi Jafar
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...RIA RUI Society
 
Servlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtpServlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtpodilodif
 
Introduction To J Boss Seam
Introduction To J Boss SeamIntroduction To J Boss Seam
Introduction To J Boss Seamashishkulkarni
 
Ajax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE EnvironmentAjax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE Environmentstarchaser
 
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and ScalaWriting highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and Scalajfarcand
 
No Va Taig April 7 2010
No Va Taig April 7 2010No Va Taig April 7 2010
No Va Taig April 7 2010rudy regner
 
JSR 168 Portal - Overview
JSR 168 Portal - OverviewJSR 168 Portal - Overview
JSR 168 Portal - OverviewVinay Kumar
 
Java Servlets
Java ServletsJava Servlets
Java ServletsNitin Pai
 
Introduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and SilverlightIntroduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and SilverlightPeter Gfader
 
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019Matt Raible
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serializationGWTcon
 
Web Applications and Deployment
Web Applications and DeploymentWeb Applications and Deployment
Web Applications and DeploymentBG Java EE Course
 

Similaire à Wicket 10 years and beyond (20)

Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applications
 
Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course
 
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
 
Web container and Apache Tomcat
Web container and Apache TomcatWeb container and Apache Tomcat
Web container and Apache Tomcat
 
Knowledge Sharing : Java Servlet
Knowledge Sharing : Java ServletKnowledge Sharing : Java Servlet
Knowledge Sharing : Java Servlet
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...
 
Beginning In J2EE
Beginning In J2EEBeginning In J2EE
Beginning In J2EE
 
Servlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtpServlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtp
 
Introduction To J Boss Seam
Introduction To J Boss SeamIntroduction To J Boss Seam
Introduction To J Boss Seam
 
Ajax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE EnvironmentAjax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE Environment
 
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and ScalaWriting highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
 
AJppt.pptx
AJppt.pptxAJppt.pptx
AJppt.pptx
 
No Va Taig April 7 2010
No Va Taig April 7 2010No Va Taig April 7 2010
No Va Taig April 7 2010
 
JSR 168 Portal - Overview
JSR 168 Portal - OverviewJSR 168 Portal - Overview
JSR 168 Portal - Overview
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
Introduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and SilverlightIntroduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and Silverlight
 
JavaEE6 my way
JavaEE6 my wayJavaEE6 my way
JavaEE6 my way
 
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
Web Applications and Deployment
Web Applications and DeploymentWeb Applications and Deployment
Web Applications and Deployment
 

Plus de Martijn Dashorst

HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0Martijn Dashorst
 
From Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsFrom Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsMartijn Dashorst
 
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLConverting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLMartijn Dashorst
 
Solutions for when documentation fails
Solutions for when documentation fails Solutions for when documentation fails
Solutions for when documentation fails Martijn Dashorst
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep DiveMartijn Dashorst
 
Scrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsScrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsMartijn Dashorst
 
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Martijn Dashorst
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeMartijn Dashorst
 
Vakmanschap is meesterschap
Vakmanschap is meesterschapVakmanschap is meesterschap
Vakmanschap is meesterschapMartijn Dashorst
 
Guide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheGuide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheMartijn Dashorst
 
Apache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaApache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaMartijn Dashorst
 

Plus de Martijn Dashorst (18)

HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
 
From Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsFrom Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud Deployments
 
SOLID principles
SOLID principlesSOLID principles
SOLID principles
 
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLConverting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
 
Solutions for when documentation fails
Solutions for when documentation fails Solutions for when documentation fails
Solutions for when documentation fails
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep Dive
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
 
Scrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsScrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijs
 
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
 
De schone coder
De schone coderDe schone coder
De schone coder
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
 
Wicket 2010
Wicket 2010Wicket 2010
Wicket 2010
 
Vakmanschap is meesterschap
Vakmanschap is meesterschapVakmanschap is meesterschap
Vakmanschap is meesterschap
 
Guide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheGuide To Successful Graduation at Apache
Guide To Successful Graduation at Apache
 
Wicket In Action
Wicket In ActionWicket In Action
Wicket In Action
 
Apache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaApache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just Java
 
Wicket Live on Stage
Wicket Live on StageWicket Live on Stage
Wicket Live on Stage
 

Dernier

A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 

Dernier (20)

A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

Wicket 10 years and beyond

  • 1. Apache Wicket
 10 years and beyond Martijn Dashorst
 topicus onderwijs @dashorst APACHE WICKET
  • 2. a brief history
 of Wicket the current state
 of Wicket the future
 of Wicket
  • 5. started in 2004 at topicus without any knowledge of web programming
  • 9. lots of XML configuration
  • 10. 1 change requires N files to be modified (for large values of N) <command name="admin.tabelbeheer.edittoetsonderdeel">
 <controller class="nl.topicus.bao.web.ctrl.lab.toetsen.
 <view name="success" path="/admin/tabelbeheer/toetsen/e
 <transform path="/mlayout/mainlayout.vm">
 <param name="_pagetitle" value="Beheer Tabellen
 </transform>
 </view>
 <view name="error" path="/admin/tabelbeheer/toetsen/edi
 <transform path="/mlayout/mainlayout.vm">
 <param name="_pagetitle" value="Beheer Tabellen
 </transform>
 </view>
 <view name="list" path="admin.tabelbeheer.edittoets.m" 
 </command>
  • 12. no back button support no multi-tab support
  • 14. little to no reuse </tr>
 #if($model.bean.absentieRegels.empty)
 <tr>
 <td colspan="19" class="border-r">#formname('groep.absent'
 </tr>
 #else
 #set($columnIndexes=[1,2,3,4,5,6,7,8,9,10])
 #foreach($row in $model.bean.absentieRegels)
 <tr>
 <td class="columnvalue">$arrayTool.elementAt($row, 0)</td
 #foreach($index in $columnIndexes)
 #set($melding=$arrayTool.elementAt($row, $index))
  • 15. complex UI neigh impossible
  • 16. a framework that makes reuse possible, minimises configuration, server side state management easy and is as type safe as possible
  • 17. Action Framework Anvil Apache Click Apache MyFaces Apache Shale Apache Sling Apache Struts Apache Struts 2 Apache Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower framework Folium FormEngine Genie Grails GWT Hamlets Helma Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw Makumba Maverick Melati Mentawai Millstone Nacho Niggle OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora Playframework Pustefix Restlet RIFE Roma Meta Framework RSF Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze Framework ZK ztemplates
  • 18. 120+ java web frameworks
  • 20. public class EditPage extends WebPage {
 private Person person;
 
 public EditPage(Person person) {
 this.person = person;
 
 add(new Button("save") {
 @Override
 public void onSubmit() {
 Entities.save(person);
 setResponsePage(new ShowPage(person));
 }
 });
 }
 }
  • 21. a framework that makes reuse possible, minimises configuration, server side state management easy and is as type safe as possible ✓ ✓ ✓ ✓
  • 22. Action Framework Anvil Apache Click Apache MyFaces Apache Shale Apache Sling Apache Struts Apache Struts 2 Apache Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower framework Folium FormEngine Genie Grails GWT Hamlets Helma Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw Makumba Maverick Melati Mentawai Millstone Nacho Niggle OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora Playframework Pustefix Restlet RIFE Roma Meta Framework RSF Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze Framework ZK ztemplates
  • 23. Action Framework Anvil Apache Click Apache MyFaces Apache Shale Apache Sling Apache Struts Apache Struts 2 Apache Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower framework Folium FormEngine Genie Grails GWT Hamlets Helma Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw Makumba Maverick Melati Mentawai Millstone Nacho Niggle OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora Playframework Pustefix Restlet RIFE Roma Meta Framework RSF Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze Framework ZK ztemplates
  • 24. 15 java web frameworks alive i.e. made any release in the last year
  • 26. What is Wicket? Apache Wicket From Wikipedia, the free encyclopedia Apache Wicket, commonly referred to as Wicket, is a lightweight component-based web application framework for the Java programming language conceptually similar to JavaServer Faces and Tapestry. It was originally written by Jonathan Locke in April 2004. Version 1.0 was released in June 2005. It graduated into an Apache top-level project in June 2007.[2]
  • 27. A brief history of Wicket
  • 28. 2004
  • 32. codehaus.org 2004 The Server Side JavaOne 1.0 1.1 2006 1.2 2005 AJAX
  • 33. 2007
  • 37. 2012 6.0 2013 2014 6.12 6.2 6.4 6.6 6.8 6.10 6.1 6.5 6.9 6.11 6.13 7.0.0-M2 6.16 6.14 6.15 7.0.0-M1 6.3 6.7 6.17 7.0.0-M3 7.0.0-M4 6.18
  • 40. 1. core 2. extensions 3. spring 4. datetime 5. auth-roles
  • 45. User Manual 195 25 Wicket Internals 25.1 Page storing During request handling, Wicket manages page instances through interface . This interface creates a new page instance ororg.apache.wicket.request.handler.IPageProvider loads a previously serialized page instance if we provide the corrisponding page id. delegatesIPageProvider page creation and retrieval to interface . When pageorg.apache.wicket.request.mapper.IPageSource class is provided delegates page creation to interface ,IPageSource org.apache.wicket.IPageFactory while when page id is provided it uses interface to load theorg.apache.wicket.page.IPageManager previously serialized page. The following workflow diagram summarizes the mechanism seen so far: IPageManager 's task is to manage which pages have been used in a requestorg.apache.wicket.page.IPageManager and store their last state in the backing stores, namely . The default implementationIPageStore collects all stateful pages which have been used in theorg.apache.wicket.page.PageStoreManager request cycle (more than one page can be used in a single request if for example orsetResponsePage() is used). At the end of the request all collected page instances are being storedRestartResponseException in the first level cache - http session. They are stored in http session attribute named and passed to the underlying"wicket:persistentPageManagerData-APPLICATION_NAME" IPageStore . When the next http request comes will ask for page with specific id andIPageProvider PageStoreManager will look first in the http session and if no match is found then it will delegate to the IPageStore. At the end of the second request the http session based cache is being overwritten completely with the newly used page instances. To setup another implementation useIPageManager . Theorg.apache.wicket.Application.setPageManagerProvider(IPageManagerProvider) custom implementation may or may not use .IPageManager IPageStore/IDataStore IPageStore 's role is to mediate the storing and loading of pages done byorg.apache.wicket.pageStore.IPageStore the underlying . The default implementationIDataStore pre-processes the pages before passing them toorg.apache.wicket.pageStore.DefaultPageStore 183 As you can see above, the Exception gets raised during the initialization of the instance evenWicketTester before the actual test method gets executed. Even though we have applied rather cool and simple annotation based test configuration already described and passed in perfectly well prepared ApplicationContext instance to the WicketTester instance in the constructor, somewhere down the rabbit hole someone complained that no WebApplicationContext instance could have been found which seems to be required in order to initialize the WicketTester properly. The problem that we run against here is due to the fact that SpringComponentInjector during its own initialization is trying to get hold of an according Spring's ApplicationContext instance that would normally be there in a runtime environment but does not find any since we are running in a test environment currently. SpringComponentInjector delegates to Spring's own WebApplicationContextUtils class to retrieve the instance of ApplicationContext out of the ServletContext which is perfectly fine for a runtime environment but is unfortunately failing in a test environment: public WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)static IllegalStateException {throws WebApplicationContext wac = getWebApplicationContext(sc); (wac == ) {if null IllegalStateException(throw new "No WebApplicationContext found: no );ContextLoaderListener registered?" } wac;return } If you still remember we defined a ContextLoaderListener in our web.xml file as part of the configuration of our runtime environment that makes sure an according WebApplicationContext instance gets initialized and registered against the ServletContext properly. Luckily, this problem can easily be solved if we slightly change the way we initialize SpringComponentInjector in our main MyWebApplication class. Apart from the constructor that we have used so far, there is another constructor in the SpringComponentInjector class that expects the caller to provide it with an according ApplicationContext instance rather than trying to resolve one on its own: public SpringComponentInjector(WebApplication webapp, ApplicationContext ctx, wrapInProxies)boolean { (webapp == )if null { IllegalArgumentException( );throw new "Argument [[webapp]] cannot be "null } (ctx == )if null { IllegalArgumentException( );throw new "Argument [[ctx]] cannot be "null } // store context in application's metadata … webapp.setMetaData(CONTEXT_KEY, ApplicationContextHolder(ctx));new // … and create and register the annotation aware injector InjectorHolder.setInjector( AnnotSpringInjector( ContextLocator(),new new
  • 46. In a Nutshell, Wicket... … has had 18,255 commits made by 62 contributors representing 318,037 lines of code … is mostly written in Java with
 a well-commented source code … has a well established, mature codebase maintained by a large development team with stable Y-O-Y commits … took an estimated 84 years of effort (COCOMO model)
 starting with its first commit in September, 2004
 ending with its most recent commit 1 days ago – openhub.net report for Wicket
  • 47.
  • 48.
  • 49.
  • 50.
  • 57. semi-monthly releases mainly bug fixes some new minor features
  • 63. public class HomePage extends WebPage { public HomePage() { add(new Label("title", "Hello!")); } }
  • 64. public class HomePage extends WebPage { public HomePage() { add(new Label("title", "Hello!")); } } <html> <body> <h1 wicket:id="title"></h1> </body> </html>
  • 65. public class HomePage extends WebPage { public HomePage() { add(new Label("title", "Hello!")); } } <html> <body> <h1 wicket:id="title"></h1> </body> </html>
  • 66. Add a <div> around content...
  • 68. <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html> public class HomePage extends WebPage {public HomePage() { add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));} }
  • 69. <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html> public class HomePage extends WebPage {public HomePage() { add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));} }
  • 70. code always follows markup in Wicket
  • 72. public class HomePage extends WebPage { public HomePage() { WebMarkupContainer container = new WebMarkupContainer("container"); add(container); add(new Label("title", "Hello!")); } } <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html>
  • 73. public class HomePage extends WebPage { public HomePage() { WebMarkupContainer container = new WebMarkupContainer("container"); add(container); add(new Label("title", "Hello!")); } } <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html>
  • 74. public class HomePage extends WebPage { public HomePage() { WebMarkupContainer container = new WebMarkupContainer("container"); add(container); container.add(new Label("title", "Hello!")); } } <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html>
  • 75. code always follows markup in Wicket or does it?
  • 76. Enter Component Queuing (coming to you in wicket 7)
  • 77. What if we delay adding components? Queue components until their location in the markup hierarchy is know markupContainer.add(new Label(...)); markupContainer.queue(new Label(...));
  • 78. public class HomePage extends WebPage {
 public HomePage() {
 WebMarkupContainer container = 
 new WebMarkupContainer("container");
 add(container);
 container.add(new Label("title", "Hello!"));
 }
 } public class HomePage extends WebPage {
 public HomePage() {
 queue(new WebMarkupContainer("container"));
 queue(new Label("title", "Hello!"));
 }
 }
  • 81. queue(new Label("label", "Some text"));
 queue(new Label("label", "Other text"));
  • 82. queue(new Label("label", "Some text"));
 queue(new Label("label", "Other text"));
  • 83. queue(new Label("first"));
 queue(new Label("last"));
 
 WebMarkupContainer secure=new WebMarkupContainer("secure") {
 public void onConfigure() {
 super.onConfigure();
 setVisible(isViewingOwnProfile());
 }
 };
 
 queue(secure);
 secure.queue(new Label("creditCardNumber"));
 secure.queue(new Label("creditCardExpiry")); Restrictions of Queuing: Ancestors
  • 84. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 85. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 86. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 </fieldset> <dt>Card number: <i wicket:id="creditCardNumber">
  • 87. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 </fieldset> <dt>Card number: <i wicket:id="creditCardNumber">
  • 88. <fieldset wicket:id="secure">
 <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 89. <fieldset wicket:id="secure">
 <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 90. Component Queuing • Wicket 7 feature • Prefer queue() when markup hierarchy can be altered • Uniqueness of Wicket IDs still requirement at same level of queuing • Can move down into child markup hierarchy • Can't move up the markup hierarchy
  • 94. public interface ILinkListener {
 void onLickClicked();
 } ILinkListener l = new ILinkListener(){
 @Override
 public void onLinkClicked() {
 System.out.println("Klik");
 }
 }
  • 95. public interface ILinkListener {
 void onLickClicked();
 } ILinkListener l = () -> {
 System.out.println("Klik");
 }
  • 96. ILinkListener l = () -> {
 System.out.println("Klik");
 } ILinkListener l = new ILinkListener(){
 @Override
 public void onLinkClicked() {
 System.out.println("Klik");
 }
 } or
  • 97. add(new Link<Void>("save") {
 @Override
 public void onClick() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }
 });
  • 98. add(new Link<Void>("save") {
 @Override
 public void onClick() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }
 });
  • 100. private void onSave() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }

  • 101. private void onSave() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }
 add(new Link<Void>("save")
 .onClick(this::onSave));

  • 102. A link with onclick, visibility and body
  • 105. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 });
  • 106. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 });
  • 107. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody());
  • 108. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 }));
  • 109. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 @Override
 public String getObject() {
 } }));
  • 110. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 @Override
 public String getObject() {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 } }));
  • 111. A link with onclick, visibility and body
  • 114. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 );

  • 115. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 );

  • 116. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 .body(() -> {
 })
 );

  • 117. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 .body(() -> {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 })
 );

  • 118. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 .body(() -> {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 })
 );
 add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 @Override
 public String getObject() {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 } })); Anon inner classes: 17 lines Java 8 lambdas: 9 lines
  • 121. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 122. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 123. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 124. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 125. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; Object result = nashorn.eval(js); try { if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 126. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } try { } catch(Exception e) { }
  • 127. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch (Exception e) { }
  • 132. Is there a future for 
 server-side frameworks?
  • 134. JavaScript Frameworks War JQuery AngularJS Ember.js React Backbone.js Meteor KnockoutJS Dojo Agility.js CanJS Polymer Mithril Maria Flight Knockback.jsAmpersand
  • 135. What is the Future for web development?
  • 136. What is the Future for web development? Web Components
  • 137. What is the Future for web development? Web Components PolymerAngularJS (2.0)
  • 138. What is the Future of Wicket?
  • 139. No Revolution but Evolution
  • 140. a brief history
 of Wicket the current state
 of Wicket the future
 of Wicket Summary