use of com.webobjects.appserver.WORequest in project wonder-slim by undur.
the class ERXSession method awake.
/**
* Overridden to provide a few checks to see if javascript is enabled.
*/
@Override
public void awake() {
super.awake();
ERXSession.setSession(this);
ERXLocalizer.setCurrentLocalizer(localizer());
NSNotificationCenter.defaultCenter().postNotification(SessionDidRestoreNotification, this);
WORequest request = context() != null ? context().request() : null;
if (request != null && log.isDebugEnabled() && request.headerForKey("content-type") != null) {
if ((request.headerForKey("content-type")).toLowerCase().indexOf("multipart/form-data") == -1)
log.debug("Form values {}", request.formValues());
else
log.debug("Multipart Form values found");
}
_originalThreadName = Thread.currentThread().getName();
Thread.currentThread().setName(threadName());
}
use of com.webobjects.appserver.WORequest in project wonder-slim by undur.
the class ERXSession method browser.
/**
* Returns the browser object representing the web browser's "user-agent"
* string. You can obtain browser name, version, platform and Mozilla
* version, etc. through this object. <br>
* Good for WOConditional's condition binding to deal with different browser
* versions.
*
* @return browser object
*/
public ERXBrowser browser() {
if (_browser == null && context() != null) {
WORequest request = context().request();
if (request != null) {
ERXBrowserFactory browserFactory = ERXBrowserFactory.factory();
if (request instanceof ERXRequest) {
_browser = ((ERXRequest) request).browser();
} else {
_browser = browserFactory.browserMatchingRequest(request);
}
browserFactory.retainBrowser(_browser);
}
}
return _browser;
}
use of com.webobjects.appserver.WORequest in project wonder-slim by undur.
the class ERXAjaxContext method _wasFormSubmitted.
@Override
@Deprecated
public boolean _wasFormSubmitted() {
boolean wasFormSubmitted = super._wasFormSubmitted();
if (wasFormSubmitted) {
WORequest request = request();
String partialSubmitSenderID = ERXAjaxApplication.partialFormSenderID(request);
if (partialSubmitSenderID != null) {
// TODO When explicitly setting the "name" binding on an input,
// the following will fail in the takeValuesFromRequest phase.
String elementID = elementID();
if (!partialSubmitSenderID.equals(elementID) && !partialSubmitSenderID.startsWith(elementID + ",") && !partialSubmitSenderID.endsWith("," + elementID) && !partialSubmitSenderID.contains("," + elementID + ",")) {
String ajaxSubmitButtonID = ERXAjaxApplication.ajaxSubmitButtonName(request);
if (ajaxSubmitButtonID == null || !ajaxSubmitButtonID.equals(elementID)) {
wasFormSubmitted = false;
}
}
}
}
return wasFormSubmitted;
}
use of com.webobjects.appserver.WORequest in project wonder-slim by undur.
the class ERXAjaxSession method savePage.
/**
* Overridden so that Ajax requests are not saved in the page cache. Checks both the
* response userInfo and the response headers if the DONT_STORE_PAGE key is present. The value doesn't matter.
* <p>
* Page Replacement cache is specifically designed to support component actions in Ajax updates. The problem with
* component actions in Ajax is that if you let them use the normal page cache, then after only 30 (or whatever your backtrack
* cache is set to) updates from Ajax, you will fill your backtrack cache. Unfortunately for the user, though, the backtrack cache
* filled up with background ajax requests, so when the user clicks on a component action on the FOREGROUND page, the
* foreground page has fallen out of the cache, and the request cannot be fulfilled (because its context is gone). If you simply
* turn off backtrack cache entirely for a request, then you can't have component actions inside of an Ajax updated area, because
* the context of the Ajax update that generated the link will never get stored, and so you will ALWAYS get a backtrack error.
* <p>
* Enter page replacement cache. If you look at the behavior of Ajax, it turns out that what you REALLY want is a hybrid page cache. You
* want to keep the backtrack of just the LAST update for a particular ajax component -- you don't care about its previous 29 states
* because the user can't use the back button to get to them anyway, but if you have the MOST RECENT cached version of the page
* then you can click on links in Ajax updated areas. Page Replacement cache implements this logic. For each Ajax component on
* your page that is updating, it keeps a cache entry of its most recent backtrack state (note the difference between this and the
* normal page cache. The normal page cache contains one entry per user-backtrackable-request. The replacement cache contains
* one entry per Ajax component*, allowing up to replacement_page_cache_size many components per page). Each time the Ajax area
* refreshes, the most recent state is replaced*. When a restorePage request comes in, the replacement cache is checked first. If
* the replacement cache can service the page, then it does so. If the replacement cache doesn't contain the context, then it
* passes up to the standard page cache. If you are not using Ajax, no replacement cache will exist in your session, and all the code
* related to it will be skipped, so it should be minimally invasive under those conditions.
* <p>
* <b>*</b> It turns out that we have to keep the last TWO states, because of a race condition in the scenario where the replacement page
* cache replaces context 2 with the context 3 update, but the user's browser hasn't been updated yet with the HTML from
* context 3. When the user clicks, they are clicking the context 2 link, which has now been removed from the replacement cache.
* By keeping the last two states, you allow for the brief period where that transition occurs.
* <p>
* Random note (that I will find useful in 2 weeks when I forget this again): The first time through savePage, the request is saved
* in the main cache. It's only on a subsequent Ajax update that it uses page replacement cache. So even though the cache
* is keyed off of context ID, the explanation of the cache being components-per-page-sized works out because each component
* is requesting in its own thread and generating their own non-overlapping context ids.
*/
@Override
public void savePage(WOComponent page) {
WOContext context = context();
if (ERXAjaxApplication.shouldNotStorePage(context)) {
if (log.isDebugEnabled())
log.debug("Considering pageReplacementCache for {} with contextID {}", context.request().uri(), context.contextID());
WORequest request = context.request();
WOResponse response = context.response();
String pageCacheKey = null;
if (response != null) {
pageCacheKey = response.headerForKey(ERXAjaxSession.PAGE_REPLACEMENT_CACHE_LOOKUP_KEY);
}
if (pageCacheKey == null && request != null) {
pageCacheKey = request.headerForKey(ERXAjaxSession.PAGE_REPLACEMENT_CACHE_LOOKUP_KEY);
}
// A null pageCacheKey should mean an Ajax request that is not returning a content update or an expliclty not cached non-Ajax request
if (pageCacheKey != null) {
log.debug("Will use pageCacheKey {}", pageCacheKey);
String originalContextID = context.request().headerForKey(ERXAjaxSession.ORIGINAL_CONTEXT_ID_KEY);
pageCacheKey = originalContextID + "_" + pageCacheKey;
LinkedHashMap pageReplacementCache = (LinkedHashMap) objectForKey(ERXAjaxSession.PAGE_REPLACEMENT_CACHE_KEY);
if (pageReplacementCache == null) {
pageReplacementCache = new LinkedHashMap();
setObjectForKey(pageReplacementCache, ERXAjaxSession.PAGE_REPLACEMENT_CACHE_KEY);
}
// Remove the oldest entry if we're about to add a new one and that would put us over the cache size ...
// We do a CACHE_SIZE*2 here because for every page, we have to potentially store its previous contextid to prevent
// race conditions, so there technically can be 2x cache size many pages in the cache.
boolean removedCacheEntry = cleanPageReplacementCacheIfNecessary(pageCacheKey);
if (!removedCacheEntry && pageReplacementCache.size() >= ERXAjaxSession.MAX_PAGE_REPLACEMENT_CACHE_SIZE * 2) {
Iterator entryIterator = pageReplacementCache.entrySet().iterator();
Map.Entry oldestEntry = (Map.Entry) entryIterator.next();
entryIterator.remove();
if (log.isDebugEnabled())
log.debug("{} pageReplacementCache too large, removing oldest entry = {}", pageCacheKey, ((TransactionRecord) oldestEntry.getValue()).key());
}
TransactionRecord pageRecord = new TransactionRecord(page, context, pageCacheKey);
pageReplacementCache.put(context.contextID(), pageRecord);
log.debug("{} new context = {}", pageCacheKey, context.contextID());
log.debug("{} = {}", pageCacheKey, pageReplacementCache.keySet());
ERXAjaxApplication.cleanUpHeaders(response);
} else {
// A null pageCacheKey should mean an Ajax request that is not returning a content update or an explicitly not cached non-Ajax request
log.debug("Not caching as no pageCacheKey found");
}
} else {
log.debug("Calling super.savePage for contextID {}", context.contextID());
super.savePage(page);
}
}
use of com.webobjects.appserver.WORequest in project wonder-slim by undur.
the class ERXComponentRequestHandler method _dispatchWithPreparedPage.
private WOResponse _dispatchWithPreparedPage(WOComponent aPage, WOSession aSession, WOContext aContext, NSDictionary someElements) {
WORequest aRequest = aContext.request();
WOApplication anApplication = WOApplication.application();
WOResponse aResponse = anApplication.createResponseInContext(aContext);
String aSenderID = aContext.senderID();
String oldContextID = aSession._contextIDMatchingIDs(aContext);
aResponse.setHTTPVersion(aRequest.httpVersion());
aResponse.setHeader("text/html", "content-type");
aContext._setResponse(aResponse);
if (oldContextID == null) {
if (aSenderID != null) {
if (aRequest._hasFormValues()) {
anApplication.takeValuesFromRequest(aRequest, aContext);
}
}
aContext._setPageChanged(false);
if (aSenderID != null) {
WOActionResults anActionResults = anApplication.invokeAction(aRequest, aContext);
if ((anActionResults == null) || ((anActionResults instanceof WOComponent))) {
WOComponent aResultComponent = (WOComponent) anActionResults;
if ((aResultComponent != null) && (aResultComponent.context() != aContext)) {
aResultComponent._awakeInContext(aContext);
}
boolean didPageChange = false;
if ((aResultComponent != null) && (aResultComponent != aContext._pageElement())) {
didPageChange = true;
}
aContext._setPageChanged(didPageChange);
if (didPageChange) {
aContext._setPageElement(aResultComponent);
}
} else {
WOResponse theResponse = anActionResults.generateResponse();
return theResponse;
}
}
} else {
WOComponent responsePage = _restorePageForContextID(oldContextID, aSession);
aContext._setPageElement(responsePage);
}
anApplication.appendToResponse(aResponse, aContext);
return aResponse;
}
Aggregations