package frostillicus.xsp.darwino.model;
import java.sql.SQLException;
import java.util.Map;
import com.darwino.commons.json.JsonException;
import com.darwino.commons.log.Logger;
import com.darwino.jsonstore.Database;
import com.darwino.jsonstore.Document;
import com.darwino.jsonstore.Store;
import frostillicus.xsp.darwino.Activator;
import frostillicus.xsp.darwino.SqlContextApplicationListener;
import frostillicus.xsp.model.ModelManager;
import frostillicus.xsp.model.ModelUtils;
/**
* @author Jesse Gallagher
* @since 1.0.0
*/
public abstract class AbstractDarwinoManager<E extends AbstractDarwinoModel> implements ModelManager<E> {
private static final long serialVersionUID = 1L;
private static final Logger log = Activator.log;
public AbstractDarwinoManager() {
if(log.isTraceEnabled()) {
log.trace("{0}: Init", getClass().getName());
}
}
@SuppressWarnings("unchecked")
protected Class<E> getModelClass() {
Class<?> enclosingClass = getClass().getEnclosingClass();
if(AbstractDarwinoModel.class.isAssignableFrom(enclosingClass)) {
return (Class<E>)enclosingClass;
}
throw new RuntimeException("No model class found.");
}
protected abstract String getConnectionBeanName();
protected abstract String getDbName();
protected String getInstanceId() {
return ""; //$NON-NLS-1$
}
protected String getStoreId() {
return Database.STORE_DEFAULT;
}
protected Database getDatabase() throws SQLException, JsonException {
return SqlContextApplicationListener.getDatabase(getConnectionBeanName(), getInstanceId(), getDbName());
}
protected Store getStore() throws JsonException, SQLException {
return getDatabase().getStore(getStoreId());
}
@Override
public Class<?> getType(Object key) {
return getModelClass();
}
@Override
public Object getValue(Object keyObject) {
if (!(keyObject instanceof String)) {
throw new IllegalArgumentException();
}
String key = (String) keyObject;
try {
Object result = null;
if ("new".equals(key)) { //$NON-NLS-1$
result = create();
} else if (ModelUtils.isUnid(key)) {
result = getById(key);
} else {
if(log.isDebugEnabled()) {
log.debug("{0}#getValue: getting named collection for {1}", getClass().getSimpleName(), keyObject); //$NON-NLS-1$
}
Map<String, Object> cacheScope = ModelUtils.getCacheScope();
String cacheKey = getClass().getName() + key;
if (!cacheScope.containsKey(cacheKey)) {
if (key.contains("^^")) { //$NON-NLS-1$
String[] bits = key.split("\\^\\^"); //$NON-NLS-1$
cacheScope.put(cacheKey, getNamedCollection(bits[0], bits.length == 1 ? "" : bits[1])); //$NON-NLS-1$
} else {
cacheScope.put(cacheKey, getNamedCollection(key, null));
}
}
result = cacheScope.get(cacheKey);
}
if(log.isDebugEnabled()) {
log.debug("{0}#getValue: returning result {1}", getClass().getSimpleName(), result);
}
return result;
} catch (Exception ne) {
// I'll want to know about this
throw ne instanceof RuntimeException ? (RuntimeException)ne : new RuntimeException(ne);
}
}
@Override
public DarwinoModelList<E> getNamedCollection(String name, String category) {
try {
return new DarwinoModelList<E>(getConnectionBeanName(), getStore(), getModelClass());
} catch(JsonException e) {
throw new RuntimeException(e);
} catch(SQLException e) {
throw new RuntimeException(e);
}
}
protected E createFromDocument(final Document doc) {
try {
E model = getModelClass().newInstance();
model.initFromDocument(getConnectionBeanName(), doc);
return model;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public E create() {
try {
E model = getModelClass().newInstance();
model.initFromStore(getConnectionBeanName(), getStore());
return model;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public E getById(String id) {
try {
Store store = getStore();
Document doc = store.loadDocument(id);
if(doc != null) {
return createFromDocument(doc);
} else {
return null;
}
} catch(JsonException e) {
throw new RuntimeException(e);
} catch(SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean isReadOnly(final Object key) {
return true;
}
@Override
public void setValue(final Object key, final Object value) {
throw new UnsupportedOperationException();
}
}