Presentation is loading. Please wait.

Presentation is loading. Please wait.

Orca: Order Recording/Customer Assets Technology Series gwl.

Similar presentations

Presentation on theme: "Orca: Order Recording/Customer Assets Technology Series gwl."— Presentation transcript:

1 Orca: Order Recording/Customer Assets Technology Series gwl

2 Orca WorkUnits A WorkUnit (WU) encapsulates a use- case. Each includes the: Screen navigation logic client-side business rules client-server communication for that use-case

3 Concept Attach a WU (indirectly) to HTTP session. It will instruct Tapestry to display the correct page, depending on its state. It will interact with the pages in that requests are funneled into the WU via component bindings/Tapestry services.

4 Concept WorkUnit services treat the attached WU as king while attached, users may only operate on that use case until done. WU is persisted between requests an attached WU may voluntarily give up control to a sub-WU if its logic allows. When done, a WU is detached from the session.

5 Concept When a sub-WU is detached, its parent regains control. A WU may veto being detached or having a sub-WU attached. WU’s delegate presentation tasks to Tapestry Pages/Components Pages/Components are bound to the WU at runtime.

6 New Customer Order Pages New Customer Order Pages Concept WU’s re-use pages WebServer Engine Visit WUWU WUWU Customer Search Page Customer Search Page MaintainCustomer Pages MaintainCustomer Pages Tapestry Pages WU Servlet Http Session

7 Concept Empower Java Developers encapsulate the use-case in a single object delegate presentation to the components that do it best (Tapestry components) Make the use-case a component too! Kill the “Back Button” problem (maybe)

8 WorkUnit data structure Page list list of strings corresponding to pages defined in Tapestry app. these are the pages this WU displays. Child WU Value is null at construction time Value is set when a subWU is attached to this one Value does not change if child is detached from this WU Value is set to null when this WU is detached. Parent WU Value is valid when this WU is attached as a child of another Value is null otherwise. Note that while WU’s can be chained, it places a burden on the size of the serialized state of the engine. Design so that the chain is not too long at any one time.

9 WU Structure (cont’d) SavedPages - a stack of visited pages CurrentPage the Tapestry name of the page this WU is showing changed by calling transition() Dirty flag Listener Map - described later

10 NullWorkUnit (NWU) Whenever no real WU is attached, NWU is automagically attached to the Visit it’s a singleton, never GC’d always allows itself to be detached never allows other WU’s to be attached to it. when NWU is in control, attachment will turf NWU, then directly attach the new WU to Visit

11 WU Lifecycle Construction Attachment Handle requests Lose control Regain control Detachment/Cleanup Constructed Attached Detached (GC) Detached (GC) Attached (No Handle Requests) Attached (No Handle Requests) Attachment Handle Requests Lose Control Regain Control Detachment

12 Lifecycle in Detail

13 Construction Right now this is simple - no-arg constructors only MyWorkUnit myNewWU = new MyWorkUnit();

14 Attachment: Attachment is made complex by Tapestry rewinding - we explain later. Some code calls (in a page here): public void startWU(IRequestCycle cycle) throws IRequestCycleException { IWorkUnit myNewWU = new CoolWorkUnit(); IWorkUnitVisit visit = (IWorkUnitVisit)getEngine().getVisit(cycle); visit.attach(myNewWU, cycle); } and the attachment process begins...

15 Case 1: NullWU attached The visit has the NWU instance attached. NWU allows always allows itself to be detached. This is the normal case when the user is not working a use- case, but wants to. Step 1 AttachDetach asks NWU if myNewWU can be attached to it. NWU always says NO! Step 2 since NWU said no, AttachDetach tries to detach NWU. NWU says yes, and is detached Step 3 AttachDetach attaches myNewWU is to the visit, and informs myNewWU of this (myNewWU.attached() ). myNewWU is now the current WU. Step 4 AttachDetach calls Visit.getWU().display(IRequestCycle cycle) - this triggers myNewWU to call cycle.setPage(getCurrentPage()); // the page myNewWU wants to show Step 2 is simplified above, AttachDetach actually tries to detach the current WU, its parent, and so on until the Visit has no WU. Any WU in the chain can veto this, and by so doing the vetoer regains control and becomes the current WU. But in this case NWU is the only one attached.

16 Case 2: Attachment rejected A WU (DirtyWorkUnit) is already attached. It will reject myNewWU as an attachment. ie, if DirtyWorkUnit didn’t want itself to be detached or any other WU to be attached to it because it has unsaved data. Step 1 AttachDetach asks DirtyWorkUnit if myNewWU can be attached to it. DirtyWorkUnit says NO because its dirty! Step 2 since DirtyWorkUnit said no, AttachDetach tries to detach DirtyWorkUnit. DirtyWorkUnit again says no, because it is dirty. Step 3 AttachDetach gives up and leaves DirtyWorkUnit as the current WU Step 4 AttachDetach calls Visit.getWU().display(IRequestCycle cycle) - this triggers DirtyWorkUnit to call cycle.setPage(getCurrentPage()); // the page DirtyWorkUnit wants to show Note that by being queried in Step 1 and 2 DirtyWorkUnit could change its state to display a “You have unsaved changes” page in Step 4

17 Case 3: Attachment accepted A WU (HappyWorkUnit) is already attached. It does not reject myNewWU as an attachment. Step 1 AttachDetach asks HappyWorkUnit if myNewWU can be attached to it. HappyWorkUnit says YES Step 2 AttacherDetacher set the parent field in myNewWU to HappyWorkUnit, the child field in HappyWorkUnit to myWorkUnit, notifies HappyWorkUnit that it has been detached, and notifies myWorkUnit that it has been attached to the visit. End result is that HappyWorkUnit has lost control. Step 3 AttachDetach calls Visit.getWU().display(IRequestCycle cycle) - this triggers DirtyWorkUnit to call cycle.setPage(getCurrentPage()); // the page DirtyWorkUnit wants to show Note that when myNewWU is detached from the visit, HappyWorkUnit is automagically re-attached and regains control.

18 Losing/Regaining Control WU’s have control only as long as they are directly attached to the Visit They lose control when detached. This will happen if the WU is removed altogether or if a child is attached to it. They will regain control if a child WU was attached to it, and then all of its descendants are detached.

19 Detachment Anyone can request a WU be detached. Even the WU in control can detach itself (and should if its ‘done’). As already described, WU’s can veto their detachment. If so the vetoer remains in control Callers can only try to detach the WU in control, otherwise a CannotDetachException is thrown and the current WU remains in control If the current WU is successfully detached and it had a parent, the parent regains control and that parent’s child field is *not* nulled out. Thus, the parent regaining control can examine the child’s state If a WU has a detached child, its child field isn’t changed until a new child is attached in its place, or until the WU itself is detached. visit.detach(aWU)

20 WorkUnit listenerMap Work Units have listeners like pages and components. WorkUnitListenerMap works like the existing Tapestry ListenerMap instead of throwing ApplicationRuntimeException, it throws StaleLinkException So, if a page was linked to method executeX() in WU1, but WU2 is in control, a StaleLinkException would be thrown if WU2 does not implement executeX() It would be possible to provide our own Stale Link page that includes the option ‘return to last know state’. Then the WU in control could be triggered to re-display its current page. public void restoreWU(IRequestCycle cycle) throws RequestCycleException { IWorkUnitVisit visit = (IWorkUnitVisit)getVisit(); visit.getWorkUnit().display(cycle); }

21 Problem: Tapestry Rewind Need to defer attachment/detachment until after rewind is done. Otherwise current WU state is not valid, it can’t reliably veto/allow an attachment/detachment request. We defer requests for attachment/detachment by using an IMonitor on the Engine. The monitor counts the rewinds and when the count drops back to 0, the AttacherDetacher is invoked

22 Interface IWorkUnit Attachment/Detachment attach(IWorkUnit) throws CannotAttachException called to request parm WU be attached as child attached(IWorkUnitVisit, IWorkUnit) called when this WU gains control detach(IWorkUnit, IRequestCycle) throws CannotDetachException called to request this WU lose control detached() called when this WU loses control

23 IWorkUnit (cont’d) Chaining support getParentWU() getChildWU() Built-in listeners cancel(IRequestCycle) throws RequestCycleException done(IRequestCycle) throws RequestCycleException Display Page support display(IRequestCycle cycle) Page dispatch logic Additional query parameters to identify component Ad-hoc code to "find" component, invoke methods Similar code in each servlet or Action that includes component Servlet / Action for component Receives request, finds component in standardized way Needs to be configured with page to render response

24 Class AbstractWorkUnit Base class for all except NWU Implements IWorkUnit includes basic functionality for pages, display, done and cancel contains default behavior for attachment/detachment

25 Class WizardWorkUnit An abstract subclass for building wizards extends AbstractWorkUnit adds listeners for next, back, done Adds methods Tapestry pages/components can use to enable/disable links/buttons. isBackButtonDisabled isNextButtonDisabled isDoneButtonDisabled

26 Using WU’s -> a Wizard Refer to code for details Defined Tapestry application: WizardTest.application Engine class = WorkUnitEngine Visit Class = WorkUnitTestVisit Pages: Home - contains a link to start the Wizard WizardWelcome - first page

27 Using WU’s -> a Wizard Pages: Home - has a link to launch wizard WizardWelcome - has Next and Cancel buttons FirstPage, SecondPage, ThirdPage - the pages for the wizard to collect name, phone, and email address each has Back, Next, Done, Cancel buttons. WorkUnits WizardTestWorkUnit - uses WizardWelcome + First/Second/Third pages

28 Wizard - starting WU’s Home has link that executes: public void launchWizard(IRequestCycle cycle) throws RequestCycleException { IWorkUnitVisit visit = IWorkUnitVisit)getEngine().getVisit(cycle); WizardTestWorkUnit wiz = new WizardTestWorkUnit(); visit.attach(wiz, cycle); } Attachment eventually calls display() on the WU which shows the WizardWelcome page.

29 Wizard - example bindings FirstPage(.jwc) has a text field + the buttons Some bindings:

Download ppt "Orca: Order Recording/Customer Assets Technology Series gwl."

Similar presentations

Ads by Google