package nebula.data.impl; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.ReentrantLock; import nebula.data.Broker; import nebula.data.DataAdapter; import nebula.data.DataStore; import nebula.data.Editable; import nebula.data.Timable; import nebula.lang.Type; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @SuppressWarnings({ "rawtypes", "unchecked" }) public class DefaultDataRepos implements DataReposEx { private Log log = LogFactory.getLog(this.getClass()); final TypeDatastore types; LoadingCache<String, DataStore<? extends Timable>> cachedDatastore; ReentrantLock lock = new ReentrantLock(); public DefaultDataRepos(TypeDatastore loader) { this.types = loader; this.cachedDatastore = CacheBuilder.newBuilder().build(new CacheLoader<String, DataStore<? extends Timable>>() { public DataStore<? extends Timable> load(final String path) throws Exception { Type type = types.getBroker(path); DataStore datastore = Broker.watch(type, new DataAdapter<Type, DataStore>() { @Override public DataStore watch(Type newData, Type oldData) { return loadDataStore(newData.getName(), newData); } }); return datastore; } }); } @Override public <V extends Timable, I> DataStore<V> define(Class<I> clzIndex, Class<V> clz, String name) { try { return (DataStore<V>)cachedDatastore.get(name); } catch (ExecutionException e) { log.error(e); throw new RuntimeException(e); } } protected DataStore loadDataStore(String name, Type type) { return new EntityDataStore(IdMakerBuilder.getIDReader(type), DefaultDataRepos.this, type); } List<Editable> changes = new ArrayList<Editable>(); @Override public void markChanged(Editable v) { lock.lock(); try { changes.add(v); } finally { lock.unlock(); } } @Override public void flush() { lock.lock(); try { for (Editable e : changes) { e.apply(); } } finally { changes.clear(); lock.unlock(); } } @Override public void clearChanges() { lock.lock(); try { changes.clear(); } finally { lock.unlock(); } } @Override public void load() { } @Override public void unload() { this.clearChanges(); } }