|
Project Wonder 2.0 | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object er.extensions.ERXComponentActionRedirector
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.
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 |
protected static final ERXLogger log
protected WOResponse originalResponse
protected WOResponse redirectionResponse
protected String sessionID
protected String url
protected static NSMutableDictionary responses
Constructor Detail |
public ERXComponentActionRedirector(ERXComponentActionRedirector.Restorable r)
Method Detail |
protected static void storeRedirector(ERXComponentActionRedirector redirector)
public static ERXComponentActionRedirector redirectorForRequest(WORequest request)
public static void createRedirector(WOActionResults results)
public static ERXComponentActionRedirector currentRedirector()
public WOResponse redirectionResponse()
public String url()
public String sessionID()
public WOResponse originalResponse()
public void setOriginalResponse(WOResponse value)
|
Last updated: Do, Dez 9, 2004 12:46 PM CET | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |