Called on 'hello' event. public void handleEventHello ... - PowerPoint PPT Presentation

1 / 64
About This Presentation
Title:

Called on 'hello' event. public void handleEventHello ...

Description:

Called on 'hello' event. public void handleEventHello ... ui:widgetInclude id='hello'/ br/ Insert your name: ... response.encodeURL('hello.jsp')% ' input ... – PowerPoint PPT presentation

Number of Views:82
Avg rating:3.0/5.0
Slides: 65
Provided by: araneafr
Category:

less

Transcript and Presenter's Notes

Title: Called on 'hello' event. public void handleEventHello ...


1
Step-by-Step Legacy Migration with Aranea
  • Jevgeni Kabanov
  • RD lead, Aranea project lead
  • Webmedia, Ltd.
  • ekabanov_at_webmedia.ee

2
Motivating scenario
  • Stakeholders have a large web application
    written in Struts. They consider Struts legacy
    and want to continue development in JSF. However
    rewriting all of the code would take too much
    time, effort and money and would halt the ongoing
    development.

3
Our solution
  • Use Aranea web integration layer to run different
    technologies side-by-side
  • Refactor the application into independent
    coarse-grained components
  • Start new development immediately and change old
    code only when requirements change step-by-step
    migration

4
(No Transcript)
5
(No Transcript)
6
(No Transcript)
7
(No Transcript)
8
Goal
  • Get rid of legacy and custom web frameworks in
    your application

9
Aranea
  • Aranea began as an Object-Oriented MVC Web
    Framework
  • From the onset we had plans to build web
    integration on the same platform
  • Aranea Integration has been released to public
    yesterday )

10
Disclaimer
  • Aranea MVC is stable and used in production
  • Aranea Integration is beta and used in pilot
    migration projects
  • Everything is Open-Source with documentation and
    support available for free from
    araneaframework.org
  • Commercial support/training/consulting is
    provided at araneaframework.com

11
Organization
  • Aranea Component Model
  • Widgets
  • Flow navigation
  • Aranea Integration Layer
  • Struts, JSF, GWT
  • Step-by-step migration
  • Principles
  • Case study

12
Aranea Component Model
  • Every component is a first-class object
  • Objects are created by the programmer
  • No (XML) mappings
  • State is in the object (no scopes)
  • Components, pages and flows are represented by
    first-class widgets

13
Hello World!
NameWidget name.jsp Reads the name from requests
and passes it to HelloWidget
HelloWidget hello.jsp Renders the Hello
name! greeting, where name is given by the
caller.
14
NameWidget
public class NameWidget extends BaseUIWidget
//Called on hello event public void
handleEventHello() String name //reads
name from request parameters (String)
getScopedData().get("name")
getFlowCtx().replace(new HelloWidget(name))

name.jsp
Insert your name ltinput typetext
namewidgetId.name"/gtltbr/gtltbr/gt
ltuieventButton labelId"Say hello"
eventId"hello"/gt
15
HelloWidget
public class HelloWidget extends BaseUIWidget
private String name //Widget state is in its
fields public HelloWidget(String name)
this.name name //We could pass any Java object
here public String getName() return
this.name public void handleEventBack()
getFlowCtx().replace(new NameWidget())
hello.jsp
Hello widget.name! ltbr/gt ltuieventButton
labelId"Back" eventId"back"/gt
16
web.xml
... ltservletgt ltservlet-namegtaraneaServletlt/ser
vlet-namegt ltservlet-classgtAraneaSpringDispatch
erServletlt/servlet-classgt ltinit-paramgt
ltparam-namegtaraneaApplicationStartlt/param-namegt
ltparam-valuegtexample.NameWidgetlt/param-valuegt
lt/init-paramgt ltload-on-startupgt1lt/load-on-
startupgt lt/servletgt ltservlet-mappinggt
ltservlet-namegtaraneaServletlt/servlet-namegt
lturl-patterngt/main/lt/url-patterngt lt/servlet-mappi
nggt ...
17
Flows
  • Currently we use replace() which means
  • A new instance is created every time
  • We know where to return


Flow1
18
Flows
  • What we would want is to preserve the instance
    and nest the new flow


Flow1

Flow2
19
Flows
  • start() and finish() do exactly that

public class NameWidget extends BaseUIWidget
... public void handleEventHello() ...
getFlowCtx().start(new HelloWidget(name))
public class HelloWidget extends BaseUIWidget
... public void handleEventBack()
getFlowCtx().finish(null)
20
Including widgets
  • Widgets can be included, lets try to use
    HelloWidget inside NameWidget like this

HelloWidget
handleEventHello()
We assume that the back button was removed from
HelloWidget
21
Including widgets
  • First lets modify the HelloWidget

public class HelloWidget extends BaseUIWidget
private String name public HelloWidget(String
name) this.name name public String
getName() return this.name public
void setName(String name) this.name
name
22
Including widgets
  • Now lets add a HelloWidget instance

public class NameWidget extends BaseUIWidget
private HelloWidget helloWidget protected
void init() helloWidget new
HelloWidget("Stranger") addWidget("hello",
helloWidget) public void
handleEventHello() String name (String)
getScopedData().get("name")
helloWidget.setName(name)
23
Including widgets
  • And finally we include the widget in the JSP

ltuiwidgetInclude id"hello"/gtltbr/gt Insert your
name ltinput type"text namewidgetId.name"/
gtltbr/gtltbr/gt ltuieventButton labelId"Say
hello" eventId"hello"/gt
24
Including widgets
  • So this is what we get

HelloWidget, helloWidget ltuiwidgetInclude
idhello/gt
helloWidget.setName(Jevgeni)
25
Widgets are objects
  • We can include several widgets of same class on
    one page

public class RootWidget extends BaseUIWidget
protected void init() addWidget("hello1",
new NameWidget()) addWidget("hello2", new
NameWidget()) addWidget("hello3", new
NameWidget())
26
Flows are objects
  • We can also include several flow containers on
    one page

public class RootWidget extends BaseUIWidget
protected void init()
addWidget("flowContainer1", new
StandardFlowContainerWidget(new NameWidget()))
addWidget("flowContainer2", new
StandardFlowContainerWidget(new NameWidget()))
addWidget("flowContainer3", new
StandardFlowContainerWidget(new NameWidget()))

27
Goal
  • Get rid of legacy and custom web frameworks in
    your application

28
Our Solution
  • Use Aranea web integration layer to run different
    technologies side-by-side
  • Refactor the application into coarse-grained
    integration components
  • Start new development immediately and change old
    code only when requirements change step-by-step
    migration

29
Requirements
  • We want to implement widgets using any
    framework/technology available
  • This can mean running a whole application in one
    widget and another application in its sibling
  • Without any changes to the technology
  • In fact we want to do that retroactively, reusing
    existing applications

30
Aranea Integration Layer
  • Integration Layer API is based around widgets
  • StrutsWidget, JsfWidget, GwtWidget
  • Widgets receive the URI of the starting point of
    the subapplication
  • E.g. new StrutsWidget(/Welcome.do)
  • AraneaUtil gives access to all of the Aranea API
    from embedded applications

31
Struts Integration Problems
  • Session and request attributes share the same
    namespace and can clash
  • Request parameter names will clash already during
    form submission
  • Struts navigates between pages by changing the
    actual URL
  • HTML limits usage of some tags

32
Problem 1 Attributes
  • We can make request attributes local, by wrapping
    HttpServletRequest and saving them in a local map
  • Since HttpSession can only be accessed via
    HttpServletRequest we can do the same thing to
    session attributes

33
Problem 2 Parameters
  • Since parameter names clash already during the
    submission of request we need to solve the
    problem in HTML
  • We can do it by introducing prefixes to each
    field name referring to the containing widget
  • The request wrapper restores the original names

34
Problem 3 Navigation
  • We put a filter over the Struts servlet that will
    include the Aranea servlet
  • While Aranea renders the particular StrutsWidget,
    it will include the according action
  • Therefore it will render in correct place as will
    everything else

35
Problem 3 Navigation
  • However we need to include some information that
    is used to render Aranea
  • Servlet path
  • Window id
  • Current widget id
  • We do that by overriding encodeURL() in request
    wrapper

36
Problem 4 HTML
  • There are two main things we need to change in
    Struts HTML output
  • Forms cannot be nested and must be escaped
  • Field names must be prefixed
  • These are easy to change using a lexer (not even
    a parser) on the output stream
  • To escape forms we construct a JavaScript object
    with the same properties/methods

37
name.jsp hello.jsp
lthtmlgt ltbodygt ltform method"get"
action"ltresponse.encodeURL("hello.jsp")gt"gt
ltinput name"name" type"text"/gt ltinput
type"submit" value"Say hello!"gt
lt/formgt lt/bodygt lt/htmlgt
lthtmlgt ltbodygt Hello param.name! lta
href"ltresponse.encodeURL("name.jsp")gt"gtBacklt/a
gt lt/bodygt lt/htmlgt
38
HelloNameWidget RootWidget
public class HelloNameWidget extends StrutsWidget
public HelloNameWidget()
super("/name.jsp")
public class RootWidget extends BaseUIWidget
protected void init() addWidget("hello1",
new HelloNameWidget()) setViewSelector("root"
)
Output
ltinput name"f0.hello1.name" type"text"/gt
ltinput type"submit" onclicknew
Aranea.Struts.Form().submit()"
value"Say hello!"gt
39
What will happen?
public class RootWidget extends BaseUIWidget
protected void init() addWidget("hello1",
new HelloNameWidget()) addWidget("hello2",
new HelloNameWidget()) addWidget("hello3",
new HelloNameWidget())
setViewSelector("root")
ltuiwidgetInclude id"hello1"/gtltbr/gtltbr/gt ltuiwidg
etInclude id"hello2"/gtltbr/gtltbr/gt ltuiwidgetInclud
e id"hello3"/gt
40
DEMO
41
Generalizing Integration
  • The approach taken with Struts can be easily
    extended to any action-based framework
  • Including custom ones
  • In fact most of it is applicable to
    component-based frameworks as well
  • However component-based frameworks will usually
    allow us to solve these problems simpler

42
JSF Integration
  • We use the same approach to encapsulate request
    and session attributes
  • Form fields can be prefixed by overriding the
    naming container (form)
  • Navigation can be solved by overridding the view
    handler
  • No postprocessing necessary!

43
DEMO
44
GWT Integration
  • Essentially the simplest, as almost everything
    happens on the client side
  • Two problems
  • Using RPC to call widget methods
  • Restoring client-side state after a full request
  • Not solved yet!

45
Our Vision
46
Goal
  • Get rid of legacy and custom web frameworks in
    your application

47
Our Solution
  • Use Aranea web integration layer to run different
    technologies side-by-side
  • Refactor the application into coarse-grained
    integration components
  • Start new development immediately and change old
    code only when requirements change step-by-step
    migration

48
Refactoring
  • Enable Aranea Integration and sanitize HTML
    (produces working application)
  • Extract layout, menu and login
  • Split application into coarse-grained components

49
Case Study
  • Estonian Tax Inspection application module
  • Connected with Forestry and European Union
    directives
  • Part of a large application family based on
    common architecture that manage all tax and
    customs needs

50
Technologies
  • MVC web framework is Struts
  • Presentation done using Velocity and Tiles
  • A lot of custom extensions to all of them
  • SSO using Weblogic API

51
Step 1 Integration HTML
  • Application started running after initial
    configuration
  • HTML ltagt tags were used in some places, which
    means encodeURL() was not applied
  • Some scripts accessed form fields by name
  • Added a widget prefix before the name

52
Step 2 Layout, menu and login
  • Since login was done using SSO we left it be
  • We extended the Aranea MenuWidget to implement
    the menu from scratch, reusing all the old
    privileges
  • After lifting header, footer and menu to the
    RootWidget turned out that Tiles were not doing
    anything useful anymore and could be eliminated

53
Step 3 How to split?
  • First we extract the widgets pointing to the
    relevant parts of the application
  • Next we change all navigation/inclusion between
    those parts to use Aranea API
  • Sending events to the hosting widget
  • AraneaUtil.getFlowCtx(), AraneaUtil.addWidget(),
    ltuihostedWidgetIncludegt used from the embedded
    applications

54
Step 3 Analyze and split
  • After some research we decided that the best way
    to split the application would be vertically by
    functionality
  • We ended up with five different functionality
    types and about ten different widgets (some
    widgets were multipurpose)

55
Step 3 Analyze and split
  • Some widgets were used only as flows while others
    were included as components
  • By extracting and abstracting several included
    widgets we eliminated a lot of copy-paste
  • While we could further refine our components it
    was good enough for starting migration

56
Results
  • Five main functionality parts which could be
    rewritten one by one without affecting the others
  • No more Tiles
  • Less copy-paste
  • If we needed to add a sixth functionality part we
    could start using JSF immediately

57
Goal
  • Get rid of legacy and custom web frameworks in
    your application

58
Our solution
  • Use Aranea web integration layer to run different
    technologies side-by-side
  • Refactor the application into coarse-grained
    integration components
  • Start new development immediately and change old
    code only when requirements change step-by-step
    migration

59
Step-by-step migration
  • After refactoring every component is a Java class
    with a particular interface/contract
  • The rest of the components can only interact with
    it via that contract
  • Therefore we can just rewrite it using any other
    implementation as long as the contract is
    preserved

60
Case study migration
  • In the case study we wanted to use Aranea, so
    there was no need for further migration
  • Eventually we would like to lift the whole Tax
    and Customs application to Aranea using other
    framework features when needed
  • However we also have clients who prefer JSF and
    Tapestry, so in those cases we would continue

61
The Next Step
  • Aranea Integration solves the problem of mashing
    up Java web applications
  • A lot of legacy applications are written in Perl,
    PHP, Oracle Forms, etc
  • Youd also want to integrate with .NET web
    applications
  • Aranea Remote Integration will support that!

62
Webmedia
  • Webmedia (www.webmedia.eu) is a Baltic company
    employing over 300 people that sponsors Aranea
    development
  • Webmedia offers complete commercial support for
    Aranea MVC Integration
  • In fact we now also offer support for migrating
    your legacy web applications to a platform of
    your choice )

63
Final Words
  • Using Aranea Integration is easy
  • Problems might come up requiring better
    understanding of Integration works
  • Migration is not completely painless, but it is
    cheap next to the alternative
  • Migrated Struts Mailreader application in the
    distribution is a good starting point

64
Questions
www.araneaframework.org
www.araneaframework.com
Write a Comment
User Comments (0)
About PowerShow.com