package jef.database;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import javax.persistence.PersistenceException;
import javax.xml.bind.annotation.XmlTransient;
import jef.accelerator.bean.BeanAccessor;
import jef.database.meta.ITableMetadata;
import jef.database.meta.MetaHolder;
import jef.database.query.Query;
import jef.database.query.QueryImpl;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* 抽象类,用于实现所有Entity默认的各种方法
*
* @author Administrator
*
*/
@SuppressWarnings("serial")
@XmlTransient
public abstract class DataObject implements IQueryableEntity {
private transient Map<Field, Object> updateValueMap;
protected transient Query<?> query;
protected transient boolean _recordUpdate = true;
private transient String _rowid;
transient ILazyLoadContext lazyload;
private static final ConditionComparator cmp = new ConditionComparator();
public final void startUpdate() {
_recordUpdate = true;
}
public final void stopUpdate() {
_recordUpdate = false;
}
public final boolean hasQuery() {
return query != null;
}
/*
* (non-Javadoc)
*
* @see jef.database.IQueryableEntity#getQuery()
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Query<?> getQuery() {
if (query == null)
query = new QueryImpl(this);
return query;
}
/*
* (non-Javadoc)
*
* @see jef.database.IQueryableEntity#clearQuery()
*/
public final void clearQuery() {
query = null;
lazyload = null;
}
/*
* (non-Javadoc)
*
* @see jef.database.IQueryableEntity#isUsed(jef.database.Field)
*/
public final boolean isUsed(Field field) {
if (updateValueMap == null)
return false;
return updateValueMap.containsKey(field);
}
/*
* (non-Javadoc)
*
* @see jef.database.query.UpdateAble#clearUpdate()
*/
public final void clearUpdate() {
updateValueMap = null;
}
/*
* (non-Javadoc)
*
* @see jef.database.query.UpdateAble#getUpdateValueMap()
*/
@SuppressWarnings("unchecked")
public final Map<Field, Object> getUpdateValueMap() {
if (updateValueMap == null)
return Collections.EMPTY_MAP;
return updateValueMap;
}
/*
* (non-Javadoc)
*
* @see jef.database.IQueryableEntity#touchUsedFlag(jef.database.Field,
* boolean)
*/
public void touchUsedFlag(Field field, boolean flag) {
if (flag) {
if (updateValueMap == null)
updateValueMap = new TreeMap<Field, Object>(cmp);
if (updateValueMap.containsKey(field)) {
return;
}
ITableMetadata meta = MetaHolder.getMeta(this);
BeanAccessor ba = meta.getContainerAccessor();
updateValueMap.put(field, ba.getProperty(this, field.name()));
} else {
if (updateValueMap != null) {
updateValueMap.remove(field);
}
}
}
public final void prepareUpdate(Field field, Object newValue) {
if (updateValueMap == null)
updateValueMap = new TreeMap<Field, Object>(cmp);
updateValueMap.put(field, newValue);
}
/**
* @deprecated will be removed in ths next release.
*/
public final void prepareUpdate(Field field, Object newValue, boolean force) {
prepareUpdate(field, newValue);
}
/*
* (non-Javadoc)
*
* @see jef.database.query.UpdateAble#needUpdate()
*/
public final boolean needUpdate() {
return (updateValueMap != null) && this.updateValueMap.size() > 0;
}
public String rowid() {
return _rowid;
}
public void bindRowid(String rowid) {
this._rowid = rowid;
}
/*
* 供子类hashCode()方法调用,判断内嵌的hashCode方法是否可用
*/
protected final int getHashCode() {
return new HashCodeBuilder().append(query).append(_recordUpdate).append(updateValueMap).toHashCode();
}
protected final void beforeSet(String fieldname) {
if (lazyload == null)
return;
lazyload.markProcessed(fieldname);
}
/*
* 处理延迟加载的字段
*/
protected final void beforeGet(String fieldname) {
if (lazyload == null)
return;
int id = lazyload.needLoad(fieldname);
if (id > -1) {
try {
if (lazyload.process(this, id)) {
lazyload = null; // 清理掉,以后不再需要延迟加载
}
} catch (SQLException e) {
throw new PersistenceException(e);
}
}
}
/*
* 供子类的equals方法调用,判断内嵌的query对象、updateMap对象是否相等
*/
protected final boolean isEquals(Object obj) {
if (!(obj instanceof DataObject)) {
return false;
}
DataObject rhs = (DataObject) obj;
return new EqualsBuilder().append(this.query, rhs.query).append(_recordUpdate, rhs._recordUpdate).append(this.updateValueMap, rhs.updateValueMap).isEquals();
}
private static class ConditionComparator implements Comparator<Field>, Serializable {
public int compare(Field o1, Field o2) {
if (o1 == o2)
return 0;
if (o1 == null)
return 1;
if (o2 == null)
return -1;
return o1.name().compareTo(o2.name());
}
}
}