package ilarkesto.persistence;
import ilarkesto.core.logging.Log;
import ilarkesto.di.Context;
import ilarkesto.fp.Predicate;
import ilarkesto.id.IdentifiableResolver;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DaoService implements IdentifiableResolver<AEntity> {
private static final Log LOG = Log.get(DaoService.class);
private Map<Class, ADao> daos = new HashMap<Class, ADao>();
public void ensureIntegrity() {
if (!initialized) throw new RuntimeException("Not initiialized!");
for (ADao dao : daos.values()) {
dao.ensureIntegrity();
}
}
public Collection<ADao> getDaos() {
return daos.values();
}
public void addDao(ADao dao) {
daos.put(dao.getEntityClass(), dao);
entityStore.load(dao.getEntityClass(), dao.getEntityName());
}
public ADao getDaoByName(String entityName) {
for (ADao manager : daos.values()) {
if (manager.getEntityName().equals(entityName)) return manager;
}
throw new RuntimeException("Dao does not exist: entityName=" + entityName);
}
public ADao getDao(AEntity entity) {
return getDaoByClass(entity.getClass());
}
public ADao getDaoByClass(Class entityClass) {
ADao dao = daos.get(entityClass);
if (dao == null) throw new RuntimeException("Dao does not exist: " + entityClass);
return dao;
}
@Override
public AEntity getById(String id) {
return getEntityById(id);
}
public AEntity getEntityById(final String id) {
if (id == null) throw new IllegalArgumentException("id == null");
AEntity entity = transactionService.getEntity(null, new Predicate<AEntity>() {
public boolean test(AEntity e) {
return id.equals(e.getId());
}
});
if (entity == null) throw new EntityDoesNotExistException(id);
return entity;
}
public boolean containsEntityWithId(final String id) {
if (id == null) throw new IllegalArgumentException("id == null");
AEntity entity = transactionService.getEntity(null, new Predicate<AEntity>() {
public boolean test(AEntity e) {
return id.equals(e.getId());
}
});
return entity != null;
}
@Override
public List<AEntity> getByIds(Collection<String> ids) {
return getEntitiesByIds(ids);
}
public Set<AEntity> getByIdsAsSet(Collection<String> ids) {
return new HashSet<AEntity>(getByIds(ids));
}
public List<AEntity> getEntitiesByIds(final Collection<String> ids) {
List<AEntity> ret = new ArrayList<AEntity>(ids.size());
for (String id : ids)
ret.add(transactionService.getById(id));
return ret;
}
// --- listeners ---
private List<DaoListener> listeners;
public void addListener(DaoListener listener) {
if (listeners == null) listeners = new ArrayList<DaoListener>();
listeners.add(listener);
}
public void removeListener(DaoListener listener) {
if (listeners == null) return;
listeners.remove(listener);
}
public void fireEntitySaved(AEntity entity) {
if (listeners == null) return;
EntityEvent event = new EntityEvent(this, entity);
for (DaoListener listener : listeners)
listener.entitySaved(event);
}
public void fireEntityDeleted(AEntity entity) {
if (listeners == null) return;
EntityEvent event = new EntityEvent(this, entity);
for (DaoListener listener : listeners)
listener.entityDeleted(event);
}
// --- dependencies ---
private volatile boolean initialized;
public synchronized final void initialize(Context context) {
if (initialized) throw new RuntimeException("Already initialized!");
for (ADao dao : context.getBeansByType(ADao.class)) {
if (dao.getEntityClass() == null) continue;
Map<String, Class> aliases = dao.getAliases();
for (Map.Entry<String, Class> entry : aliases.entrySet()) {
entityStore.setAlias(entry.getKey(), entry.getValue());
// TODO remove
String subpackageAndClass = entry.getValue().getName().substring(12);
entityStore.setAlias("org.organizanto.app.domain." + subpackageAndClass, entry.getValue());
LOG.debug("alias:", "org.organizanto.app.domain." + subpackageAndClass);
}
}
for (ADao dao : context.getBeansByType(ADao.class)) {
if (dao.getEntityClass() == null) continue;
dao.initialize(context);
addDao(dao);
}
initialized = true;
}
private EntityStore entityStore;
public void setEntityStore(EntityStore entityStore) {
this.entityStore = entityStore;
}
private TransactionService transactionService;
public void setTransactionService(TransactionService transactionService) {
this.transactionService = transactionService;
}
}