package ring.nrapi;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.UUID;
import org.xmldb.api.base.XMLDBException;
import ring.nrapi.business.BusinessObject;
import ring.persistence.Loadpoint;
import ring.persistence.XQuery;
/**
* The in-memory index of game objects. The ObjectIndex implements a {@link java.util.WeakHashMap}
* to relate UUIDs to BusinessObjects. This in-memory index is backed by and synchronized with
* the XML datastore. The XML datastore is used for creating a list of UUIDs as a result of an
* XPath search.
* @author projectmoon
*
*/
public class ObjectIndex {
private WeakHashMap<UUID, WeakReference<BusinessObject>> index = new WeakHashMap<UUID, WeakReference<BusinessObject>>();
private ReferenceQueue<BusinessObject> refQueue;
public synchronized void addObject(BusinessObject bo) {
WeakReference<BusinessObject> ref = new WeakReference<BusinessObject>(bo, refQueue);
index.put(bo.getUuid(), ref);
if (bo.isRoot()) {
insertObject(bo);
}
}
public synchronized BusinessObject get(UUID key) {
WeakReference<BusinessObject> ref = index.get(key);
if (ref != null) {
return ref.get();
}
else {
return null;
}
}
public synchronized BusinessObject removeKey(UUID key) {
return index.remove(key).get();
}
protected synchronized void removeAll() {
index.clear();
}
protected Collection<BusinessObject> getAll() {
Set<BusinessObject> bos = new HashSet<BusinessObject>();
for (WeakReference<BusinessObject> ref : index.values()) {
bos.add(ref.get());
}
return bos;
}
public List<BusinessObject> getAll(List<UUID> keys) {
List<BusinessObject> bos = new ArrayList<BusinessObject>(keys.size());
for (UUID key : keys) {
BusinessObject bo = get(key);
bos.add(bo);
}
return bos;
}
private void insertObject(BusinessObject bo) {
try {
InputStream query = this.getClass().getResourceAsStream("/ring/nrapi/index_insert.xq");
XQuery xq = new XQuery(query);
xq.setLoadpoint(Loadpoint.GAME);
String queryString = xq.getQuery();
queryString = queryString.replace("$bo", bo.toXML());
xq.setQuery(queryString);
xq.executeUpdate();
}
catch (XMLDBException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
protected void setReferenceQueue(ReferenceQueue<BusinessObject> refQueue) {
this.refQueue = refQueue;
}
}