You can do this pretty well now with the beans scope, with one caveat that the bean is an NSF specification. Despite the fact that the XSP Starter set, in my opinion, includes an example of how to make a server bean (which is really a singleton, that is, there is only one instance of the class for the entire JVM).
First, create a simple serializable POJO called CachedData, which has two members, the first is a field that contains a date time value that indicates when you last read data from disk, and the second is some kind of list object, like a vector which contains your values.
Then create another POJO called ServerMap, which has a map <string, map <string, map <string, map <Object, map <object, CachedData> gt; > gt; > gt; as a member, and a function called doCachedLookup () or something like that. The parameters of this function can be almost the same as @DbLookup, server, database, view, key, etc. Then in doCachedLookup check your ServerMap for the specified server as the key. If this does not exist, create a new card and insert it into ServerMap with the key being the server name. If it exists, then find the database name on this map, then the view on the next map, and then finally the value on the last map. When you receive the CachedData object, you can check the date date field and see if it has expired, if not, return the vector, and if it is, drop it, then perform a new search and re-cache the data, and then return the vector.
Here are code examples, I was a bit lazy in my overloaded methods to get the column and get the field name, and I use some deprecated java date methods, but it will give you a good base to start with. All code checked:
CachedData Class:
package com.ZetaOne.example; import java.io.Serializable; import java.util.Date; import java.util.Vector; public class CachedData implements Serializable { private static final long serialVersionUID = 1L; private Date updateTime; private Vector<Object> values; public Date getUpdateTime() { return this.updateTime; } public void setUpdateTime(Date UpdateTime) { updateTime = UpdateTime; } public Vector<Object> getValues() { return this.values; } public void setValues(Vector<Object> values) { this.values = values; } }
The CachedLookup class, which is implemented as a singleton, so that it can be used on the server:
package com.ZetaOne.example; import java.io.Serializable; import java.util.Date; import java.util.Vector; import com.ZetaOne.example.CachedData; import java.util.HashMap; import java.util.Collections; import java.util.Map; import lotus.domino.Session; import lotus.domino.Database; import lotus.domino.View; import lotus.domino.NotesException; import lotus.domino.ViewEntryCollection; import lotus.domino.ViewEntry; import lotus.domino.Document; import javax.faces.context.FacesContext; public class CachedLookup implements Serializable { private static CachedLookup _instance; private static final long serialVersionUID = 1L; private Map<String, HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>> cachedLookup; public static CachedLookup getCurrentInstance() { if (_instance == null) { _instance = new CachedLookup(); } return _instance; } private CachedLookup() { HashMap<String, HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>> cachedLookupMap = new HashMap<String, HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>>(); this.cachedLookup = Collections.synchronizedMap(cachedLookupMap); } @SuppressWarnings("deprecation") public Vector<Object> doCachedLookup(String serverName, String filePath, String viewName, Object keyValues, int columnNumber, boolean exactMatch) { if (cachedLookup.containsKey(serverName)) { if (cachedLookup.get(serverName).containsKey(filePath)) { if (cachedLookup.get(serverName).get(filePath).containsKey(viewName)) { if (cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) { if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(columnNumber)) { CachedData cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(columnNumber); if (cache.getUpdateTime().compareTo(new Date()) > 0) { System.out.println("Cache Hit"); return cache.getValues(); } } } } } } System.out.println("Cache Miss");
XPage example:
<xp:text id="text1"> <xp:this.value><![CDATA[#{javascript: com.ZetaOne.example.CachedLookup.getCurrentInstance().doCachedLookup( database.getServer(), database.getFilePath(), "lookup", "Test Category", "Value", true ) }]]></xp:this.value> </xp:text>