
org.xillium.gear.util.CacheSpace Maven / Gradle / Ivy
package org.xillium.gear.util;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.Callable;
import org.xillium.base.beans.Beans;
import org.xillium.base.beans.Strings;
import org.xillium.data.DataObject;
import org.xillium.data.persistence.ObjectMappedQuery;
import org.xillium.core.Persistence;
import org.xillium.gear.model.coordinate;
/**
* CacheSpace is an n-dimensional cartesian space to hold data objects, which can be assigned to either points or subspaces.
* Subspace-level data objects provide subspace-wide global values for all points within, but are overridden by values from
* data objects assigned to points. A CacheSpace is always arranged so that a fully populated data object be assigned to the
* whole space, ensuring that data values exist at every point in the space.
* Data objects in a CacheSpace must define 2 kinds of data members: coordinates and values.
*
* - Coordinate members must be of String type, and collectively form an ordered sequence that constitues the coordinate
* system. Each coordinate member is annotated with
@coordinate
annotation specifying its order in the
* coordinate system.
* - Value members must be of object types so that missing values can be clearly denoted by nulls.
*
*/
public class CacheSpace {
/**
* A "match-any" coordinate wildcard.
*/
public static final String ANY = "-";
/**
* Constructs a CacheSpace from a data object retriever. The retriever gives the data object class and the means to
* load data objects from external resources.
*
* @param retriever a data object retriever whose type parameter {@code T} is the class of the data objects
*/
public CacheSpace(Callable> retriever) {
_toplevel = new TopLevel(deriveDataClass(retriever), retriever);
}
/**
* Constructs a CacheSpace from a data object class. Data objects are retrieved from a database table whose name matches
* that of the data object class.
*
* @param persistence a Persistence object
* @param type the type of data objects
*/
public CacheSpace(Persistence persistence, Class type) {
_toplevel = new TopLevel(type, new DatabaseObjectRetriever(persistence, type));
}
/**
* Looks up a data object at a particular coordinate.
*
* @param keys the keys that form the coordinate
*/
public T get(String... keys) {
return _toplevel.get(keys, 0);
}
/**
* Counts the number of data objects in the space.
*/
public int count() {
return _toplevel.count();
}
/**
* (Re)loads data objects from an external source.
*/
public void reload() {
try {
if (_toplevel.specifics != null) _toplevel.specifics.clear();
_toplevel.global = null;
for (T object: _toplevel.retriever.call()) {
_toplevel.insert(object, _toplevel.coordinates, 0);
}
if (_toplevel.global == null) throw new IllegalStateException("***GlobalDataObjectMissing");
_toplevel.spread();
} catch (Exception x) {
throw new RuntimeException(x.getMessage(), x);
}
}
private final TopLevel _toplevel;
@SuppressWarnings("unchecked")
private static Class deriveDataClass(Callable> c) {
return (Class)((ParameterizedType)((ParameterizedType)c.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]).getActualTypeArguments()[0];
}
private static class DatabaseObjectRetriever implements Callable> {
private final Persistence _persistence;
private final Persistence.Task, Void> _task;
public DatabaseObjectRetriever(Persistence persistence, Class type) {
final ObjectMappedQuery statement = new ObjectMappedQuery(type);
statement.set("SELECT * FROM " + Strings.splitCamelCase(type.getSimpleName(), "_").toUpperCase());
_persistence = persistence;
_task = new Persistence.Task, Void>() {
public List run(Void v, Persistence persistence) throws Exception {
return statement.getResults(persistence.getConnection(), null);
}
};
}
public List call() {
return _persistence.doReadOnly(null, _task);
}
}
private static class Block {
public T global;
public Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy