1 / 58

Object-Oriented Web Development with Aranea

Object-Oriented Web Development with Aranea. Jevgeni Kabanov R&D lead, Webmedia, Ltd. JavaZone, Oslo, 13 th September, 2006. Outline. Introduction Aranea “Hello World!” and beyond Applying OO to web With real-life examples taken from Aranea-based projects Behind the scenes

eferrero
Download Presentation

Object-Oriented Web Development with Aranea

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Object-Oriented Web Development with Aranea Jevgeni Kabanov R&D lead, Webmedia, Ltd. JavaZone, Oslo, 13th September, 2006

  2. Outline • Introduction • Aranea “Hello World!” and beyond • Applying OO to web • With real-life examples taken from Aranea-based projects • Behind the scenes • Where’s the catch? • Uniting Web Frameworks OO Web Development

  3. Motivation • At the moment web applications are barely reusable! • Existing code cannot be reused for similar requirements without inserting if-then-else-s everywhere • Legacy migration is very hard! • Integrating applications built on different platforms is hard and often visible to user • Object-Oriented Design to the rescue! OO Web Development

  4. Web is • Procedural (Client calls server) • Synchronized (One window – one request) • Decomposable into pages • Client is mostly stateless (Current state with result, cookies) • In general web is based around a concept of a page, which is combining data, behavior and presentation OO Web Development

  5. GUI applications are • Mostly stateful • Mostly synchronized (one window – one thread) • Decomposable into components • Comfortable to represent using OO concepts • Model-View-Controller pattern suggest to keep data, presentation and behavior separately OO Web Development

  6. Enter MVC Web Frameworks • Request-based: Struts, Spring MVC • Page-based: JSF, Wicket, Tapestry • Continuation/flow-based: RIFE, Spring WebFlow • AJAX-based: Echo2, GWT • … • OO-based: Wicket, Aranea OO Web Development

  7. Problems with OO in Web • Encapsulation & Abstraction (broken) • External state management (session) • Poor contracts among components • Polymorphism (broken) • XML mappings • Implicit component creation • Components, pages & flows are typically not first class objects! OO Web Development

  8. Enter Aranea • An Object-Oriented Web Framework • Everything is an object (component) • Objects are created by the programmer • No (XML) mappings • State is in the object (no session) • Supports • Stateless request-based services • Stateful session-based widgets • Components, pages and flows are represented by widgets OO Web Development

  9. 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. Note that we need two widgets only for demonstration purposes OO Web Development

  10. NameWidget • init() is called when the widget life cycle begins • setViewSelector(“name”) resolves (in this case) to “name.jsp” publicclass NameWidget extends BaseUIWidget { protectedvoid init() { setViewSelector("name"); } //To be continued… } OO Web Development

  11. name.jsp • ui:systemForm renders an HTML form • ui:eventButton renders an HTML button that submits event “hello” • Event “hello” maps to widget method “handleEventHello” (or a listener) <ui:systemForm method="GET"> Insert your name: <input type="text“ name="name"/><br/><br/> <ui:eventButton labelId="#Say hello" eventId="hello"/> </ui:systemForm> OO Web Development

  12. NameWidget • getInputData().getGlobalData() is a map of request parameters • getFlowCtx().replace() replaces the current flow widget with the new one publicclass NameWidget extends BaseUIWidget { publicvoid handleEventHello() { String name = (String) getInputData().getGlobalData().get("name"); getFlowCtx().replace(new HelloWidget(name), null); } } OO Web Development

  13. HelloWidget publicclass HelloWidget extends BaseUIWidget { private String name;//Widget state is in its fields public String getName() {returnthis.name;} public HelloWidget(String name) { this.name = name; } protectedvoid init() throws Exception { setViewSelector("hello"); } } hello.jsp Hello <c:out value="${widget.name}"/>! OO Web Development

  14. Hello World! reexamined NameWidget name.jsp handleEventHello() getFlowCtx().replace(new HelloWidget(name)); HelloWidget hello.jsp OO Web Development

  15. Reusing widgets • Widgets can be reused, let’s try to use HelloWidget inside NameWidget like this HelloWidget handleEventHello() OO Web Development

  16. Reusing widgets • First let’s modify the HelloWidget: publicclass HelloWidget extends BaseUIWidget { private String name; public String getName() {returnthis.name;} publicvoid setName(String name) {this.name = name;} public HelloWidget(String name) { this.name = name; } protectedvoid init() throws Exception { setViewSelector("hello"); } } OO Web Development

  17. Reusing widgets • We can use HelloWidget directly in the NameWidget: publicclass NameWidget extends BaseUIWidget { private HelloWidget helloWidget; protectedvoid init() throws Exception { helloWidget = new HelloWidget("Stranger"); addWidget("hello", helloWidget); setViewSelector("name"); } //… } OO Web Development

  18. Reusing widgets • We can just call the instance method as usual: publicclass NameWidget extends BaseUIWidget { //… publicvoid handleEventHello() throws Exception { String name = (String) getInputData().getGlobalData().get("name"); helloWidget.setName(name); } } • This works since widget state is preserved OO Web Development

  19. Reusing widgets • And we include the widget in the JSP <ui:systemForm method="GET"> <ui:widgetInclude id="hello"/><br/> Insert your name: <input type="text“ name="name"/><br/><br/> <ui:eventButton labelId="#Say hello" eventId="hello"/> </ui:systemForm> • <ui:widgetInclude> tag just asks widget to render itself OO Web Development

  20. Reusing widgets • So this is what we get: HelloWidget, helloWidget <ui:widgetInclude id=“hello”/> helloWidget.setName(“Jevgeni”) OO Web Development

  21. Real-life reuse example Widget #1 Widget #2 OO Web Development

  22. Real-life reuse example Widget #1 Widget #2 OO Web Development

  23. Real-life reuse example • Reusing allows composing widgets together to form a use case • The widgets may in their turn be composed of other widgets and so on • This is an implementation of the Composite pattern for the Controller • The main difference from mashup is widget being an object OO Web Development

  24. Widgets are objects • This allows, e.g. to add three widgets of same class in one use case: publicclass UseCaseWidget extends BaseUIWidget { protectedvoid init() { addWidget("client1", new ClientEditWidget(firstClientId)); addWidget("client2", new ClientEditWidget(secondClientId)); addWidget("client3", new ClientEditWidget(thirdClientId)); } } • This also allows abstracting away from a particular widget OO Web Development

  25. Polymorphism • Now let’s modify the NameWidget to be polymorphic: publicclass NameWidget extends BaseUIWidget { private IHelloWidget helloWidget; public NameWidget(IHelloWidget helloWidget) { this.helloWidget = helloWidget; } protectedvoid init() throws Exception { addWidget("hello", helloWidget); setViewSelector("name"); } //… } OO Web Development

  26. Polymorphism • Where IHelloWidget is: publicinterface IHelloWidget extends Widget { publicvoid setName(String name); } • Now we can easily e.g. search Google for the inserted name: OO Web Development

  27. Polymorphism • To do that we just make a GoogleHelloWidget: publicclass GoogleHelloWidget implements IHelloWidget { privateint hits; publicvoid setName(String name) { //Connect to Google... this.hits = //Get number of hits... } //... select JSP and render } • And we can get the previous use case withnew NameWidget(new GoogleHelloWidget()) OO Web Development

  28. Real-life polymorphism • Polymorphism is a very powerful tool of abstraction • One of the uses of polymorphism in web is to make a use case depend on its context • E.g. context use case can assign either a generic client search, or a dropdown list component OO Web Development

  29. Use case variant #1 Widget #1 Client search widget Widget #2 OO Web Development

  30. Use case variant #2 Widget #1 Client select widget Widget #2 OO Web Development

  31. Use case implementation • Implementation would look like this: publicclass UseCaseWidget extends BaseUIWidget { privateIClientWidget clientWidget; public UseCaseWidget(IClientWidget clientWidget) { this.clientWidget = clientWidget; } protectedvoid init() { addWidget("widget1", new Widget1()); addWidget("client", clientWidget); addWidget("widget2", new Widget2()); } } OO Web Development

  32. Use case implementation • But what can IClientWidget look like? • It might be something like that: publicinterface IClientWidget extends Widget { publicboolean isFound(); public Client getClient(); } • But we don’t really know when the user selects a client! OO Web Development

  33. Use case implementation • What we need is a callback: interface IClientWidget extends Widget { interface Callback { void clientSelected(Client client); } void setCallback(Callback callback); } • Polymorphism with callbacks makes for a very powerful abstraction OO Web Development

  34. Use case implementation • Our use case would use callback like this: publicclass UseCaseWidget extends BaseUIWidget implements IClientWidget.Callback { private IClientWidget clientWidget; public UseCaseWidget(IClientWidget clientWidget) { this.clientWidget = clientWidget; clientWidget.setCallback(this); } void clientSelected(Client client) { //... } } Note that use case widget functions as a Mediator! OO Web Development

  35. Flows • A different use case is when we display the search on a separate page and then return the result OO Web Development

  36. Flows • Flows are pages which preserve nested state and can return values OO Web Development

  37. Flows examined • Flow container is a widget that contains a stack of widgets representing flows • It provides the following interface (context) publicinterface FlowContext { void start(Widget flow, Handler handler); void replace(Widget flow) void finish(Object result); void cancel(); } • But how flows and their children can access this interface? OO Web Development

  38. Environment • Environment allows parents to let children access their features interface Environment { Object getEntry(Object key); } Usage example: FlowContext flowCtx = (FlowContext ) //Java 5, where are you? getEnvironment().getEntry(FlowContext.class); flowCtx.start(new MyWidget()); Note that environment is context-dependent! OO Web Development

  39. Wrapping flows • The last example (IClientWidget) was a reusable polymorphic widget providing a callback • However we might also want to wrap it in a flow: publicclassClientFlowWidgetextends BaseUIWidget implements IClientWidget.Callback { private IClientWidget clientWidget; publicClientFlowWidget(IClientWidget clientWidget) { this.clientWidget = clientWidget; clientWidget.setCallback(this); } void clientSelected(Client client) { //getFlowCtx() is just an environment lookup method getFlowCtx().finish(client); } } OO Web Development

  40. First-class flow container • A relatively common use case is to have some kind of context set up for the use cases under it • E.g. one can have a number of use cases depending on the client being already selected • Aranea allows to do such use cases easily by creating a new flow container and adding an Environment entry OO Web Development

  41. First-class flow container Client (or in this case patient) context Use case OO Web Development

  42. First-class flow container • Implementation would look like this: publicclass ClientContextWidget implements ClientContext { private Client client; public ClientContextWidget(Client client) {this.client = client;} public Client getClient() {returnthis.client;} protectedvoid init() { //Add this to Environment under ClientContext.class addWidget("clientInfo", new ClientInfoWidget(client)); addWidget("flowContainer", new StandardFlowContainer(new UseCaseWidget())); } } OO Web Development

  43. First-class flow container • Where the ClientContext is: interface ClientContext { Client getClient(); } • Now all the navigation under the ClientContextWidget will be constrained to its flow container • And all widgets under it will be able to access the selected client OO Web Development

  44. Performance • Widget-based applications require HTTP sessions • We have support for saving state to client • For stateless operation one should use stateless services that can still reuse widgets • There are no known problems with the processing time OO Web Development

  45. Security • Since neither widgets nor flows are identified by URLs there is no way to access them by URL/Request hacking • This removes a lot of security checks! • In fact it is common to check rights only when creating a use case widget • If one still needs bookmarking, one can use mounting service, which will map URLs explicitly OO Web Development

  46. Back button handling • At the moment Aranea ignores the forward/back button in the default configuration for widgets • However, included client state filter supports back button as intended • We also plan to add support for • Explicit back button handling • Automated state-based back button handling OO Web Development

  47. And more… • Multi-submit protection • Popup isolation • No problems with session • Database-backed lists • Generating query with filter conditions, order and range • Keyboard events • AJAX (both full and partial updates) OO Web Development

  48. A word about the framework • Framework is built using the same component types as in applications • This makes it • Modular • Configurable • Extensible • In fact each of our current applications has some extensions to the framework OO Web Development

  49. Integration • Our goal is to use Aranea component model to structure our application • And then use it as glue to integrate with all other web frameworks • In fact Aranea was specially designed with integration in mind • But before 1.0 release we had to put our energy elsewhere OO Web Development

  50. The BIG Picture OO Web Development

More Related