|
introduction get started articles manual tutorials reference docs case studies knowledge base goodies screenshots demos echoes Carousel zone home forums downloads bugs mailing list |
XUI Zone - articles
How the CacheManager orchestrates data between the client and server The CacheManager class takes care of loading cached accounts and contact information via local routes and non-cached applications via remote routes. Figure 1 shows a screenshot of the offline menu and the cache settings shown in the cache column.
Figure 1 - The offline menu with showing the cache states of the accounts
This cache information is stored in the cachedaccounts.xml file on the local filesystem. Each data item within the file has a cachestate attribute which is shown in the table. More information on how the table is bound to the cache file can be found here As an example of how the CacheManager is used within the application, have a look at the code in listing 1 which is taken from the AccountSearch class. The first line calls the retrieveAccount method of the CacheManager which is shown in listing 2. The next line makes use of the XPageManager class in order to load and show the accountsummary page. More about how the XPageManager class is used within the Sugar Rich Client application can be seen here.
Listing 1 - Calling CacheManager retrieveAccount method from AccountSearch class
cacheMgr.retrieveAccount( mdl.getId() ); pageMgr.showPage( "accountsummary" ); The retriveAccount method shown in listing 2 uses the XModelHelper class to set the id of the selected account in a temporary node of the XModel.
Listing 2 - The event declaration
public void retrieveAccount( String id ) { XModelHelper.setTempVar( "selectedaccount", id ); if ( !isAccountCached() ) { accRetrieve.retrieveAccount( id ); setAccountCacheState( CacheConstants.CACHE_READ ); saveCacheFile(); } } The isAccountCached function shown in listing 3 checks to see if the account is already loaded into the application cache. It once again uses the XModelHelper class to get the id of the selected account. The getCachedState function uses the get method of the XModel to retrive the selected account node from the XModel structure. The getAttrib function of the XModelHelper retrieves the cachestate attribute of the selected account node. If the account is not cached the AccountRetrieve class is used to retrieve the account details. This class makes a call to a route which connects to the tomcat server and is described in more detail in the remote routes section of this case study. The next line in listing 2 sets the cache state of the retrieved account to CACHE_READ meaning that is has simply been read and not modified.
Listing 3 - Getting the cache state
public boolean isAccountCached() { return getCachedState( "retrievedaccounts/" + getSelectedAccount() ); } public String getSelectedContact() { return XModelHelper.getTempVar( "selectedcontact" ); } private boolean getCachedState( String path ) { XBaseModel mdl = ( XBaseModel )rootModel.get( path ); String cachestate = XModelHelper.getAttrib( mdl, "cachestate" ); if ( cachestate == null ) return false; if ( cachestate.compareTo( CacheConstants.CACHE_NEW ) == 0 ) return true; if ( cachestate.compareTo( CacheConstants.CACHE_MODIFIED ) == 0 ) return true; else return true; } The last call in listing 2 is to the saveCacheFile function which saves the cache file to the sugar user directory. The saveCacheFile function is explained in more detail in the section on local routes. When the Edit account button in figure 1 is clicked, the code shown in listing 4 which is taken from the OfflineMenu class is invoked.
Listing 4 - The editAccount method of the OfflineMenu class
public void editAccount() { SpecificModelAdapter sma = ( SpecificModelAdapter )accountsTable.getModel(); XModel mdl = ( XModel ) sma.getModelAt( accountsTable.getSelectedRow() ); cacheMgr.setSelectedAccount( mdl.getId() ); AccountPage page = ( AccountPage ) pageMgr.showPage( "accountpage" ); String cacheState = XModelHelper.getAttrib( mdl, "cachestate" ); if ( cacheState.compareTo( CacheConstants.CACHE_STUB ) == 0 ) page.setEntryMode( AccountPage.ENTRY_MODE_NEW ); else page.setEntryMode( AccountPage.ENTRY_MODE_EXISTING ); } The first two lines of the function deal with retrieving the selected account id from the table. This is explained in further detail in the section on table bindings. In the next line the setSelectedAccount of the CacheManager is called with the value of the selected account id. The CacheManager simply calls the setTempVar of the XModelHelper class which sets the value of the XModel at the path temp/selectedaccount to the account id as shown in listing 5.
Listing 5 - The setSelectedAccount method of the XModelHelper class
public void setSelectedAccount( String id ) { XModelHelper.setTempVar( "selectedaccount", id ); } The next line in listing 4 uses the XPageManager to show the accountpage.xml page. The cachestate attribute of the selected table model is checked to see if it is a new or existing account and sets the mode of the page accordingly. When the accountpage.xml is displayed, the bindings are automatically updated to reflect the values of the selected account as shown in figure 2 below. Now when the Save Account button of the accountpage is clicked the code shown in listing 6 which is taken from the EntryPage class is invoked.
Listing 6 - The edit method of the EntryPage class
public void save() { int valid = checkValidations(); if ( valid == XValidator.LEVEL_IGNORE ) { saveDetails(); cacheMgr.saveCacheFile(); pageMgr.showPrevious(); } } When the validations are checked and passed the saveDetails method of the the AccountPage class which extends the EntryPage class is called.
Listing 7 - The saveDetails method of the AccountPage class
public void saveDetails() { saveBindings(); String cacheState = ( entryMode == ENTRY_MODE_NEW ) ? CacheConstants.CACHE_NEW : CacheConstants.CACHE_MODIFIED; cacheMgr.swapAccountStateNode( cacheState ); } The swapAccountStateNode of the CacheManager class which is shown in listing 8 below is called.
Listing 8 - The swapAccountStateNode method of the CacheManager class
public void swapAccountStateNode( String state ) { XBaseModel mdl = ( XBaseModel )rootModel.get( "xui_state/retrievedaccounts/" + getSelectedAccount() ); XBaseModel dataMdl = ( XBaseModel )rootModel.get( "retrievedaccounts/" + getSelectedAccount() ); swapStateNode( mdl, dataMdl ); setAccountCacheState( state ); } private void swapStateNode( XBaseModel mdl, XBaseModel dataMdl ) { XBaseModel parent = ( XBaseModel )dataMdl.getParent(); XModelHelper.merge( dataMdl, XModelHelper.clone( mdl ) ); } This method swaps the xui_state node with the original node in the retrievedaccounts node making sure that the cache is saved with the correct data. The merge method of the XModelHelper class takes the changes made in the xui_state and updates the original node with them. Finally the saveCacheFile of the CacheManager class is called in order to persist the cache to the local cache file which is described in the section on local routes. comments If you were logged in you could rate this article or add a comment. |