Project Wonder 2.0

er.extensions
Class ERXComponentActionRedirector

java.lang.Object
  extended byer.extensions.ERXComponentActionRedirector

public class ERXComponentActionRedirector
extends Object

Allows you to develop your app using component actions while still providing bookmarkable URLs. It should be considered highly experimental and it uses a few very dirty shortcuts, but no private API to work it's magic. The main problems may be garbabe collection or space requirements. You might be better of to compress the responses. The mode of operation is as follows; given a component action in a typical page: public WOComponent myAction() { WOComponent nextPage = pageWithName("Main"); nextPage.takeValueForKey(new Integer(100), "someValue"); return nextPage; } then Main could be implemented something like this: public class Main extends WOComponent implements ERXComponentActionRedirector.Restorable { static ERXLogger log = ERXLogger.getERXLogger(Main.class); public Integer someValue = new Integer(10); public Main(WOContext aContext) { super(aContext); } // this page has a "Incement Some Value" link to itself which just doubles the current value public WOComponent addAction() { someValue = new Integer(someValue.intValue()*2); log.info(someValue); return this; } public String urlForCurrentState() { return context().directActionURLForActionNamed("Main$Restore", new NSDictionary(someValue, "someValue")); } public static class Restore extends WODirectAction { public Restore(WORequest aRequest) { super(aRequest); } public WOActionResults defaultAction() { WOComponent nextPage = pageWithName("Main"); Number someValue = context().request().numericFormValueForKey("someValue", new NSNumberFormatter("#")); if(someValue != null) { nextPage.takeValueForKey(someValue, "someValue"); } return nextPage; } } } But this is just one possibility. It only locates all the code in one place. The actual workings are: You create a page with typical component action links URL in browser: /cgi-bin/WebObjects/myapp.woa/ Links on page: /cgi-bin/WebObjects/myapp.woa/0.1.2.3 When you click on a link, the request-response loop gets executed, but instead of returning the response, we save it in a session-based cache and return a redirect instead. The current page is asked for the URL for the redirect when it implements the Restorable interface. So the users browser receives redirection to a "reasonable" URL like "/article/1234/edit?wosid=..." or "../wa/EditArticle?__key=1234&wosid=...". This URL is intercepted and looked up in the cache. If found, the stored response is returned, else the request is handled normally. The major thing about this class is that you can detach URLs from actions. For example, it is very hard to create a direct action that creates a page that uses a Tab panel or a collapsible component because you need to store a tremendous amount of state in the URL. With this class, you say: "OK, I won't be able to totally restore everything, but I'll show the first page with everything collapsed. For all of this to work, your application should override the request-response loop like: public WOActionResults invokeAction(WORequest request, WOContext context) { WOActionResults results = super.invokeAction(request, context); ERXComponentActionRedirector.createRedirectorInContext(results, context); return results; } public void appendToResponse(WOResponse response, WOContext context) { super.appendToResponse(response, context); ERXComponentActionRedirector redirector = ERXComponentActionRedirector.currentRedirector(); if(redirector != null) { redirector.setOriginalResponse(response); } } public WOResponse dispatchRequest(WORequest request) { ERXComponentActionRedirector redirector = ERXComponentActionRedirector.redirectorForRequest(request); WOResponse response = null; if(redirector == null) { response = super.dispatchRequest(request); redirector = ERXComponentActionRedirector.currentRedirector(); if(redirector != null) { response = redirector.redirectionResponse(); } } else { response = redirector.originalResponse(); } return response; } Instead of the code above, you should be able to simply use ERXApplication and set the er.extensions.ERXComponentActionRedirector.enabled=true property.

Author:
ak

Nested Class Summary
static class ERXComponentActionRedirector.Observer
          Observer class manages the responses cache by watching the session.
static interface ERXComponentActionRedirector.Restorable
          implemented by the pages that want to be restorable
 
Field Summary
protected static ERXLogger log
          logging support
protected  WOResponse originalResponse
          the original response
protected  WOResponse redirectionResponse
          the redirection response
protected static NSMutableDictionary responses
          static cache to hold the responses.
protected  String sessionID
          the session id for the request
protected  String url
          the url for the redirected request
 
Constructor Summary
ERXComponentActionRedirector(ERXComponentActionRedirector.Restorable r)
          contructs the redirector from the Restorable.
 
Method Summary
static void createRedirector(WOActionResults results)
          Creates and stores a Redirector if the given results implement Restorable.
static ERXComponentActionRedirector currentRedirector()
          returns the currently active Redirector in the request-response loop.
 WOResponse originalResponse()
           
 WOResponse redirectionResponse()
           
static ERXComponentActionRedirector redirectorForRequest(WORequest request)
          returns the previously stored redirector for the given request.
 String sessionID()
           
 void setOriginalResponse(WOResponse value)
          sets the original response.
protected static void storeRedirector(ERXComponentActionRedirector redirector)
          stores the redirector in the cache.
 String url()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

protected static final ERXLogger log
logging support


originalResponse

protected WOResponse originalResponse
the original response


redirectionResponse

protected WOResponse redirectionResponse
the redirection response


sessionID

protected String sessionID
the session id for the request


url

protected String url
the url for the redirected request


responses

protected static NSMutableDictionary responses
static cache to hold the responses. They are stored on a by-session basis.

Constructor Detail

ERXComponentActionRedirector

public ERXComponentActionRedirector(ERXComponentActionRedirector.Restorable r)
contructs the redirector from the Restorable.

Method Detail

storeRedirector

protected static void storeRedirector(ERXComponentActionRedirector redirector)
stores the redirector in the cache.


redirectorForRequest

public static ERXComponentActionRedirector redirectorForRequest(WORequest request)
returns the previously stored redirector for the given request.


createRedirector

public static void createRedirector(WOActionResults results)
Creates and stores a Redirector if the given results implement Restorable.


currentRedirector

public static ERXComponentActionRedirector currentRedirector()
returns the currently active Redirector in the request-response loop. Uses ERXThreadStorage with the key "redirector".


redirectionResponse

public WOResponse redirectionResponse()
Returns:
the redirection response.

url

public String url()
Returns:
the URL with which the component can be restored.

sessionID

public String sessionID()
Returns:
the session ID for the Redirector.

originalResponse

public WOResponse originalResponse()
Returns:
the original response.

setOriginalResponse

public void setOriginalResponse(WOResponse value)
sets the original response.


Last updated: Do, Dez 9, 2004 • 12:46 PM CET

Copyright © 2002 – 2004 Project Wonder.