Project Wonder 5.0

er.extensions.appserver.ajax
Class ERXAjaxSession

java.lang.Object
  extended by com.webobjects.appserver.WOSession
      extended by er.extensions.appserver.ajax.ERXAjaxSession
All Implemented Interfaces:
com.webobjects.foundation.NSKeyValueCoding, com.webobjects.foundation.NSKeyValueCoding.ErrorHandling, com.webobjects.foundation.NSKeyValueCodingAdditions, java.io.Serializable, java.lang.Cloneable
Direct Known Subclasses:
ERXSession

public class ERXAjaxSession
extends com.webobjects.appserver.WOSession

ERXAjaxSession is the part of ERXSession that handles Ajax requests. If you want to use the Ajax framework without using other parts of Project Wonder (i.e. ERXSession or ERXApplication), you should steal all of the code in ERXAjaxSession, ERXAjaxApplication, and ERXAjaxContext.

See Also:
Serialized Form
Author:
mschrag

Nested Class Summary
 
Nested classes/interfaces inherited from interface com.webobjects.foundation.NSKeyValueCodingAdditions
com.webobjects.foundation.NSKeyValueCodingAdditions.DefaultImplementation, com.webobjects.foundation.NSKeyValueCodingAdditions.Utility
 
Nested classes/interfaces inherited from interface com.webobjects.foundation.NSKeyValueCoding
com.webobjects.foundation.NSKeyValueCoding._BooleanFieldBinding, com.webobjects.foundation.NSKeyValueCoding._BooleanMethodBinding, com.webobjects.foundation.NSKeyValueCoding._FieldBinding, com.webobjects.foundation.NSKeyValueCoding._ForwardingBinding, com.webobjects.foundation.NSKeyValueCoding._KeyBinding, com.webobjects.foundation.NSKeyValueCoding._KeyBindingCreation, com.webobjects.foundation.NSKeyValueCoding._MethodBinding, com.webobjects.foundation.NSKeyValueCoding._NumberFieldBinding, com.webobjects.foundation.NSKeyValueCoding._NumberMethodBinding, com.webobjects.foundation.NSKeyValueCoding._ReflectionKeyBindingCreation, com.webobjects.foundation.NSKeyValueCoding.ErrorHandling, com.webobjects.foundation.NSKeyValueCoding.Null, com.webobjects.foundation.NSKeyValueCoding.UnknownKeyException, com.webobjects.foundation.NSKeyValueCoding.ValueAccessor
 
Field Summary
protected  com.webobjects.foundation.NSMutableArray _permanentContextIDArray
          The currently active contextIDs for the permanent pages.
protected  com.webobjects.foundation.NSMutableDictionary _permanentPageCache
          A dict of contextID/pages
static java.lang.String DONT_STORE_PAGE
          Key that tells the session not to store the current page.
static java.lang.String FORCE_STORE_PAGE
           
static java.lang.String PAGE_REPLACEMENT_CACHE_LOOKUP_KEY
          Key that is used to specify that a page should go in the replacement cache instead of the backtrack cache.
 
Fields inherited from class com.webobjects.appserver.WOSession
_componentState, _httpSession, _httpSessionWatcher, SessionDidCreateNotification, SessionDidRestoreNotification, SessionDidTimeOutNotification
 
Fields inherited from interface com.webobjects.foundation.NSKeyValueCoding.ErrorHandling
_CLASS
 
Fields inherited from interface com.webobjects.foundation.NSKeyValueCodingAdditions
_CLASS, _KeyPathSeparatorChar, KeyPathSeparator
 
Fields inherited from interface com.webobjects.foundation.NSKeyValueCoding
NullValue
 
Constructor Summary
ERXAjaxSession()
           
ERXAjaxSession(java.lang.String sessionID)
           
 
Method Summary
protected  com.webobjects.foundation.NSMutableDictionary _permanentPageCache()
          Returns the permanent page cache.
protected  com.webobjects.appserver.WOComponent _permanentPageWithContextID(java.lang.String contextID)
          Returns the page for the given contextID, null if none is present.
 void _saveCurrentPage()
          Semi-private method that saves the current page.
protected  boolean _shouldPutInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
          Reimplementation of the rather wierd super imp which references an interface probably no one has ever heard of...
protected  void cleanPageReplacementCacheIfNecessary()
          Iterates through the page replacement cache (if there is one) and removes expired records.
protected  boolean cleanPageReplacementCacheIfNecessary(java.lang.String _cacheKeyToAge)
          Iterates through the page replacement cache (if there is one) and removes expired records.
 com.webobjects.appserver.WOComponent restorePageForContextID(java.lang.String contextID)
          Extension of restorePageForContextID that implements the other side of Page Replacement Cache.
 void savePage(com.webobjects.appserver.WOComponent page)
          Overridden so that Ajax requests are not saved in the page cache.
 void savePageInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
          Saves a page in the permanent cache.
 
Methods inherited from class com.webobjects.appserver.WOSession
_allowToViewEvents, _allowToViewStatistics, _appendCookieToResponse, _awakeInContext, _birthDate, _clearCookieFromResponse, _contextCounter, _contextDidIncrementContextID, _contextIDMatchingIDs, _formattedStatistics, _keyEnumerator, _lifeInMillis, _requestCounter, _setContext, _setHttpSession, _setHttpSessionWatcher, _setSessionID, _sleepInContext, _terminateByJ2EE, _terminateByTimeout, allowedToViewEvents, allowedToViewStatistics, appendToResponse, awake, canAccessFieldsDirectly, clone, context, debugString, defaultEditingContext, domainForIDCookies, expirationDateForIDCookies, handleQueryWithUnboundKey, handleTakeValueForUnboundKey, invokeAction, isDistributionEnabled, isTerminating, languages, logString, objectForKey, removeObjectForKey, sessionID, setDefaultEditingContext, setDistributionEnabled, setLanguages, setObjectForKey, setStoresIDsInCookies, setStoresIDsInURLs, setTimeOut, sleep, statistics, storesIDsInCookies, storesIDsInURLs, takeValueForKey, takeValueForKeyPath, takeValuesFromRequest, terminate, timeOut, timeOutForIDCookies, timeOutMillis, toString, unableToSetNullForKey, validateEventsLogin, validateStatisticsLogin, validationFailedWithException, valueForKey, valueForKeyPath
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DONT_STORE_PAGE

public static final java.lang.String DONT_STORE_PAGE
Key that tells the session not to store the current page. Checks both the response userInfo and the response headers if this key is present. The value doesn't matter, but you need to update the corresponding value in AjaxUtils. This is to keep the dependencies between the two frameworks independent.

See Also:
Constant Field Values

FORCE_STORE_PAGE

public static final java.lang.String FORCE_STORE_PAGE
See Also:
Constant Field Values

PAGE_REPLACEMENT_CACHE_LOOKUP_KEY

public static final java.lang.String PAGE_REPLACEMENT_CACHE_LOOKUP_KEY
Key that is used to specify that a page should go in the replacement cache instead of the backtrack cache. This is used for Ajax components that actually generate component actions in their output. The value doesn't matter, but you need to update the corresponding value in AjaxUtils. This is to keep the dependencies between the two frameworks independent.

See Also:
Constant Field Values

_permanentPageCache

protected com.webobjects.foundation.NSMutableDictionary _permanentPageCache
A dict of contextID/pages


_permanentContextIDArray

protected com.webobjects.foundation.NSMutableArray _permanentContextIDArray
The currently active contextIDs for the permanent pages.

Constructor Detail

ERXAjaxSession

public ERXAjaxSession()

ERXAjaxSession

public ERXAjaxSession(java.lang.String sessionID)
Method Detail

savePage

public void savePage(com.webobjects.appserver.WOComponent page)
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.

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.

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.

* 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.

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.

Overrides:
savePage in class com.webobjects.appserver.WOSession

cleanPageReplacementCacheIfNecessary

protected void cleanPageReplacementCacheIfNecessary()
Iterates through the page replacement cache (if there is one) and removes expired records.


cleanPageReplacementCacheIfNecessary

protected boolean cleanPageReplacementCacheIfNecessary(java.lang.String _cacheKeyToAge)
Iterates through the page replacement cache (if there is one) and removes expired records.

Parameters:
_cacheKeyToAge - optional cache key to age via setOldPage
Returns:
whether or not a cache entry was removed

_permanentPageCache

protected com.webobjects.foundation.NSMutableDictionary _permanentPageCache()
Returns the permanent page cache. Initializes it if needed.


_permanentPageWithContextID

protected com.webobjects.appserver.WOComponent _permanentPageWithContextID(java.lang.String contextID)
Returns the page for the given contextID, null if none is present.

Parameters:
contextID -

_saveCurrentPage

public void _saveCurrentPage()
Semi-private method that saves the current page. Overridden to put the page in the permanent page cache if it's already in there.

Overrides:
_saveCurrentPage in class com.webobjects.appserver.WOSession

_shouldPutInPermanentCache

protected boolean _shouldPutInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
Reimplementation of the rather wierd super imp which references an interface probably no one has ever heard of...

Parameters:
wocomponent -

savePageInPermanentCache

public void savePageInPermanentCache(com.webobjects.appserver.WOComponent wocomponent)
Saves a page in the permanent cache. Overridden to not save in the super implementation's iVars but in our own.

Overrides:
savePageInPermanentCache in class com.webobjects.appserver.WOSession

restorePageForContextID

public com.webobjects.appserver.WOComponent restorePageForContextID(java.lang.String contextID)
Extension of restorePageForContextID that implements the other side of Page Replacement Cache.

Overrides:
restorePageForContextID in class com.webobjects.appserver.WOSession

Last updated: Tue, Feb 21, 2017 • 05:45 PM CET

Copyright © 2002 – 2007 Project Wonder.