package de.flower.rmt.ui.model;
import de.flower.common.model.db.entity.IEntity;
import de.flower.common.util.Check;
import org.apache.wicket.injection.Injector;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author flowerrrr
*/
public abstract class AbstractEntityModel<T extends IEntity> extends LoadableDetachableModel<T> {
private final static Logger log = LoggerFactory.getLogger(AbstractEntityModel.class);
private Long id;
private IModel<T> wrappedModel;
public AbstractEntityModel() {
this((T) null);
}
public AbstractEntityModel(Long id) {
this.id = id;
init();
}
public AbstractEntityModel(T entity) {
if (entity != null) {
setObject(entity);
this.id = entity.getId();
}
init();
}
/**
* Allow overwriting for unit tests
*/
protected void init() {
Injector.get().inject(this);
}
public AbstractEntityModel(IModel<T> model) {
this((T) null);
Check.notNull(model);
wrappedModel = model;
}
public Long getId() {
if (id == null) {
id = getObject().getId();
}
return id;
}
/**
* If the entity was transient when the modal was created, but has been persisted
* in the meantime, set the id of the entity so that the persisted entity will be loaded the
* next time the entity is requested.
*/
@Override
protected void onDetach() {
if (getObject() != null) {
this.id = getObject().getId();
}
// once we detach this model we discard any wrapped model. the call to getObject() will have
// initialized the id of the entity so we can reload it next time.
if (wrappedModel != null) {
//noinspection AssignmentToNull
wrappedModel = null;
}
}
@Override
protected T load() {
// if we have a model then try to get the object from there.
T object;
try {
if (wrappedModel != null) {
object = wrappedModel.getObject();
} else {
if (id == null) {
object = newInstance();
} else {
object = load(id);
}
}
} catch (RuntimeException e) {
log.error("load(): " + e.getMessage(), e);
throw e;
}
if (!nullAllowed()) {
Check.notNull(object);
}
return object;
}
protected boolean nullAllowed() {
return false;
}
abstract protected T load(Long id);
protected T newInstance() {
throw new UnsupportedOperationException("Method not implemented. Model should only be used for persisted entities!");
}
}