È può benissimo farlo ora con scope scope, con l'avvertenza che un bean è specifico NSF. Anche se il kit Starter XSP credo includa un esempio di come fare un bean con scope Server (che è in realtà un singleton, il che significa che esiste solo un'istanza della classe per l'intera JVM).
Per prima cosa creare un POJO serializzabile semplice chiamato CachedData con due campi membro, il primo è un campo che contiene un valore di data e ora che indica l'ultima volta in cui i dati sono stati letti dal disco e il secondo è una sorta di oggetto elenco , come un vettore, che contiene i tuoi valori.
Quindi creare un altro POJO chiamato ServerMap che ha una stringa cartina <, carta < stringa, carta < stringa, carta < oggetto, carta < oggetto, CachedData > > > > come membro, e una funzione chiamata doCachedLookup() o qualcosa del genere. I parametri di tale funzione possono essere quasi gli stessi di @DbLookup, server, database, vista, chiave, ecc. Quindi, in doCachedLookup, controlla la tua ServerMap per l'esistenza del server specificato come chiave. Se non esiste, quindi creare una nuova mappa e inserirla in ServerMap con la chiave come nome del server. Se esiste, cerca il nome del database in quella mappa, quindi la vista nella mappa successiva e infine il valore nell'ultima mappa. Una volta ottenuto l'oggetto CachedData, è possibile controllare il campo relativo alla data e vedere se è scaduto, se non lo è, restituire il vettore, e se lo è, scartarlo, quindi eseguire una nuova ricerca e ricollegare la cache i dati e quindi restituire il vettore.
Ecco gli esempi di codice, ero un po 'pigro nei miei metodi di overload per ottenere una colonna rispetto a ottenere un nome di campo, e io uso di alcuni metodi di data java deprecati, ma vi darà una buona base da cui partire. Tutto il codice è testato:
CachedData Classe: Classe
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;
}
}
CachedLookup che viene implementato come un Singleton in modo che possa essere utilizzato in tutto il 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");
// if we drop to here, cache is either expired or not present, do the lookup.
try {
Session session = (Session)resolveVariable("session");
Database db = session.getDatabase(serverName, filePath);
View view = db.getView(viewName);
ViewEntryCollection vc = view.getAllEntriesByKey(keyValues, exactMatch);
ViewEntry ve, vn;
ve = vc.getFirstEntry();
Vector<Object> results = new Vector<Object>();
while (ve != null) {
results.add(ve.getColumnValues().elementAt(columnNumber));
vn = vc.getNextEntry();
ve.recycle();
ve = vn;
}
vc.recycle();
if (!cachedLookup.containsKey(serverName)) {
cachedLookup.put(serverName, new HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>());
}
if (!cachedLookup.get(serverName).containsKey(filePath)) {
cachedLookup.get(serverName).put(filePath, new HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>());
}
if (!cachedLookup.get(serverName).get(filePath).containsKey(viewName)) {
cachedLookup.get(serverName).get(filePath).put(viewName, new HashMap<Object, HashMap<Object, CachedData>>());
}
if (!cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) {
cachedLookup.get(serverName).get(filePath).get(viewName).put(keyValues, new HashMap<Object, CachedData>());
}
CachedData cache;
if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(columnNumber)) {
cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(columnNumber);
} else {
cache = new CachedData();
}
Date dt = new Date();
dt.setHours(dt.getHours() + 1);
cache.setUpdateTime(dt);
cache.setValues(results);
cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).put(columnNumber, cache);
view.recycle();
db.recycle();
return results;
} catch (NotesException e) {
// debug here, im lazy
return null;
}
}
public Vector<Object> doCachedLookup(String serverName, String filePath, String viewName, Object keyValues, String fieldName, 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(fieldName)) {
CachedData cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(fieldName);
if (cache.getUpdateTime().compareTo(new Date()) > 0) {
System.out.println("Cache Hit");
return cache.getValues();
}
}
}
}
}
}
System.out.println("Cache Miss");
// if we drop to here, cache is either expired or not present, do the lookup.
try {
Session session = (Session)resolveVariable("session");
Database db = session.getDatabase(serverName, filePath);
View view = db.getView(viewName);
ViewEntryCollection vc = view.getAllEntriesByKey(keyValues, exactMatch);
ViewEntry ve, vn;
ve = vc.getFirstEntry();
Vector<Object> results = new Vector<Object>();
while (ve != null) {
Document doc = ve.getDocument();
results.add(doc.getItemValue(fieldName));
doc.recycle();
vn = vc.getNextEntry();
ve.recycle();
ve = vn;
}
vc.recycle();
if (!cachedLookup.containsKey(serverName)) {
cachedLookup.put(serverName, new HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>());
}
if (!cachedLookup.get(serverName).containsKey(filePath)) {
cachedLookup.get(serverName).put(filePath, new HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>());
}
if (!cachedLookup.get(serverName).get(filePath).containsKey(viewName)) {
cachedLookup.get(serverName).get(filePath).put(viewName, new HashMap<Object, HashMap<Object, CachedData>>());
}
if (!cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) {
cachedLookup.get(serverName).get(filePath).get(viewName).put(keyValues, new HashMap<Object, CachedData>());
}
CachedData cache;
if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(fieldName)) {
cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(fieldName);
} else {
cache = new CachedData();
}
Date dt = new Date();
dt.setHours(dt.getHours() + 1);
cache.setUpdateTime(dt);
cache.setValues(results);
cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).put(fieldName, cache);
view.recycle();
db.recycle();
return results;
} catch (NotesException e) {
// debug here, im lazy
return null;
}
}
private static Object resolveVariable(String variable) {
return FacesContext.getCurrentInstance().getApplication()
.getVariableResolver().resolveVariable(
FacesContext.getCurrentInstance(), variable);
}
}
esempio su come utilizzare in una XPage:
<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>
Per essere sicuro, deve essere un plug-in osgi? O potrebbe anche essere fatto con un bean utente definito nel database? Dove sono archiviate le informazioni sui database di ricerca? – jjtbsomhorst
Potrebbe essere un bean definito in un plug-in OSGi. Il mio pensiero è che averlo nel plugin lo renderà globale per il server, quindi qualsiasi app che deve effettuare una ricerca può semplicemente chiamare la funzione per restituire un valore. I database di ricerca si trovano in una posizione fissa sul server. –