gu.sql2java.BaseRow Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sql2java-base Show documentation
Show all versions of sql2java-base Show documentation
sql2java common class package
package gu.sql2java;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Map.Entry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.gitee.l0km.beanfilter.CodecPhase;
import com.gitee.l0km.beanfilter.CodecScope;
import com.gitee.l0km.beanfilter.ICombinedFilter;
import com.gitee.l0km.beanfilter.InterceptorContext;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
import gu.sql2java.exception.UnsupportTypeException;
import static com.google.common.base.Preconditions.*;
import static gu.sql2java.BaseTypeColumnCodec.BASE_CODEC;
import static gu.sql2java.BaseTypeColumnCodec.isBaseColumnType;
import static gu.sql2java.utils.DeepCloneUtils.cloneFields;
import static gu.sql2java.utils.BaseTypeTransformer.asUnsignedLongChecked;
import static gu.sql2java.utils.BaseTypeTransformer.INTERGRAL_CLASSES;
import static gu.sql2java.utils.ColumnTransformer.COLUMN_TRANSFORMER;
/**
* abstract implementation of {@link BaseBean}
* @author guyadong
*
*/
public abstract class BaseRow implements BaseBean,Comparable, Cloneable {
protected final RowMetaData metaData;
private volatile Map mapView;
protected BaseRow(RowMetaData metaData) {
this.metaData = checkNotNull(metaData,"metaData is null");
}
protected BaseRow() {
this.metaData = checkNotNull(RowMetaData.getMetaData(getClass()),"metaData is null");
}
@Override
public final boolean isInitialized(String column) {
return isInitialized(metaData.columnIDOf(column));
}
@Override
public boolean beModified() {
for(int i=0; i 0) {
for(int i=0; i < columnIDs.length; ++i){
if(isModified(columnIDs[i])){
return true;
}
}
}
return false;
}
@Override
public boolean isModified(String... columns){
if(null != columns && columns.length > 0) {
for(int i=0; i < columns.length; ++i){
if(isModified(columns[i])){
return true;
}
}
}
return false;
}
@Override
public boolean isModified(String column){
return isModified(metaData.columnIDOf(column));
}
@Override
public boolean isModifiedNested(String nestedName){
if(null == nestedName){
return false;
}
if(isModified(nestedName)){
return true;
}
String prefix = metaData.tablename + ".";
if(nestedName.startsWith(prefix)){
/** remove table name */
nestedName = nestedName.substring(prefix.length());
}
int firstDot = nestedName.indexOf('.');
if(firstDot > 0){
/** 0-firstDot is column name */
return isModified(nestedName.substring(0, firstDot));
} if(firstDot == 0){
/** column name is empty */
return false;
}else {
/** only column name */
return isModified(nestedName);
}
}
@Override
public int[] modifiedColumnIDs(){
List list = Lists.newArrayListWithCapacity(metaData.columnCount);
for(int columnID = 0; columnID < metaData.columnCount;++columnID){
if(isModified(columnID)){
list.add(columnID);
}
}
return Ints.toArray(list);
}
@Override
public String[] modifiedColumns(){
return Iterables.toArray(metaData.columnNamesOf(modifiedColumnIDs()),String.class);
}
@Override
public int modifiedColumnCount(){
return modifiedColumnIDs().length;
}
@Override
public void modified(int[] columnIDs) {
if(null != columnIDs){
for(int columnID : columnIDs){
modified(columnID);
}
}
}
@Override
public void modified(int columnID,int ...columnIDs) {
modified(columnID);
modified(columnIDs);
}
@Override
public void modified(String column) {
modified(metaData.columnIDOf(column));
}
@Override
public void modified(String[] columns) {
if(null != columns){
for(String column : columns){
modified(metaData.columnIDOf(column));
}
}
}
@Override
public void modified(String column,String... columns) {
modified(column);
modified(columns);
}
@Override
public void resetModified(int[] columnIDs) {
if(null != columnIDs){
for(int columnID:columnIDs){
resetModified(columnID);
}
}
}
@Override
public void resetModified(int columnID, int... columnIDs) {
resetModified(columnID);
resetModified(columnIDs);
}
@Override
public void resetModified(String column) {
resetModified(new int[]{metaData.columnIDOf(column)});
}
@Override
public void resetModified(String column, String... columns) {
resetModified(column);
resetModified(columns);
}
@Override
public void resetModified(String[] columns) {
if(null != columns){
for(String column:columns){
resetModified(column);
}
}
}
@Override
public void resetModifiedIfEqual() {
/** exist record from database */
BaseBean saved = loadSaved();
if(null!= saved) {
for (int columnID = 0; columnID < metaData.columnCount; ++columnID) {
if (isModified(columnID) && Objects.deepEquals(saved.getValue(columnID), getValue(columnID))) {
resetModified(columnID);
}
}
}
}
/**
* try retrieving the corresponding record based on the primary key(has no null) and return it.
* Otherwise, return null
* only run on database service side
* @since 4.3.4
*/
@SuppressWarnings("unchecked")
public B loadByPk() {
TableManager manager;
if ((manager = metaData.getManagerUnchecked()) != null) {
/** exist record from database */
B old = manager.loadByPrimaryKey(primaryValues());
if (null != old) {
return (B) old.clone();
}
}
return null;
}
/**
* If {@link #isNew} is {@code false},
* try retrieving the corresponding record based on the primary key and return it.
* Otherwise, return null
* only run on database service side
* @since 3.32.6
*/
public B loadSaved() {
if (!isNew()) {
return loadByPk();
}
return null;
}
@Override
public void resetPrimaryKeysModified()
{
for(int pkIds:metaData.primaryKeyIds) {
resetModified(pkIds);
}
}
@Override
public void resetModifiedExceptPrimaryKeys()
{
for(int columnID=0; columnID T getValue(String column) {
return getValue(metaData.columnIDOf(column));
}
@Override
public final T getValueChecked(int columnID) {
T value = getValue(columnID);
return Preconditions.checkNotNull(value,"value of columnid %s IS NULL", columnID);
}
@Override
public final T getValueChecked(String column) {
T value = getValue(column);
return Preconditions.checkNotNull(value,"value of column %s IS NULL", column);
}
@Override
public final void setValue(String column, Object value) {
setValue(metaData.columnIDOf(column),value);
}
@Override
public final boolean setValueIfNonNull(String column, Object value)
{
return setValueIf(value != null,column,value);
}
@Override
public final boolean setValueIfNonEqual(String column, Object value)
{
return setValueIf(!Objects.equals(value, getValue(column)),column,value);
}
@Override
public final boolean setValueIf(boolean expression,String column, Object value)
{
if(expression){
setValue(column,value);
}
return expression;
}
@SuppressWarnings("unchecked")
@Override
public T getValue(int columnID)
{
try {
return (T) metaData.getterMethods.get(columnID).invoke(this);
} catch (IndexOutOfBoundsException e) {
return null;
}catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public T getOriginValue(int columnID)
{
try {
Class> fieldType = metaData.fieldTypeOf(columnID);
Method getter = metaData.getterMethods.get(columnID);
if(getter.getReturnType().isAssignableFrom(fieldType)) {
return (T)getter.invoke(this);
}else {
Method reader = metaData.readMethods.get(columnID);
checkState(null != reader,"NOT DEFINED read method for %s",metaData.columnNameOf(columnID));
return (T) reader.invoke(this);
}
} catch (IndexOutOfBoundsException e) {
return null;
}catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
@Override
@SuppressWarnings("unchecked")
public T getJdbcValue(int columnID)
{
try {
Class> jdbcType = metaData.jdbcTypeOf(columnID);
Method getter = metaData.getterMethods.get(columnID);
if(getter.getReturnType().isAssignableFrom(jdbcType)) {
return (T)getter.invoke(this);
}
Method reader = metaData.readMethods.get(columnID);
if(null != reader) {
if(reader.getReturnType().isAssignableFrom(jdbcType)) {
return (T) reader.invoke(this);
}
if(isBaseColumnType(reader.getReturnType())) {
return (T) BASE_CODEC.serialize(reader.invoke(this), jdbcType);
}
}
ColumnCodec codec = metaData.columnCodecOf(columnID);
if(null != codec) {
return (T) codec.serialize(getOriginValue(columnID), jdbcType);
}
throw new IllegalStateException(String.format("CAN NOT GET VALUE OF %d AS %s",columnID,jdbcType));
} catch (IndexOutOfBoundsException e) {
return null;
}catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
private void setValue(Method setMethod,T value) throws IllegalArgumentException
{
try {
setMethod.invoke(this, value);
} catch ( IllegalArgumentException e) {
if(isBaseColumnType(value)) {
Class> expectType = setMethod.getParameterTypes()[0];
if(isBaseColumnType(expectType)) {
try {
setValue(setMethod,BASE_CODEC.deserialize(value, expectType));
return;
} catch (UnsupportTypeException e2) {
// DO NOTHING
}
}
}
throw e;
}catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
@Override
public void setValue(int columnID,T value)
{
try {
setValue(metaData.setterMethods.get(columnID), value);
} catch (IndexOutOfBoundsException e) {
return ;
}catch ( IllegalArgumentException e) {
Method writeMethod = metaData.writeMethods.get(columnID);
if(null != writeMethod) {
setValue(writeMethod, value);
return;
}
throw e;
}
}
@Override
public final boolean setValueIfNonNull(int columnID,T value)
{
return setValueIf(value != null,columnID,value);
}
@Override
public final boolean setValueIfNonEqual(int columnID,T value)
{
return setValueIf(!Objects.equals(value, getValue(columnID)),columnID,value);
}
@Override
public final boolean setValueIf(boolean expression,int columnID,T value)
{
if(expression){
setValue(columnID,value);
}
return expression;
}
@Override
public final boolean testBitValue(int columnID,Number mask, boolean bitOr) {
long m = asUnsignedLongChecked(mask);
if(m == 0L) {
return false;
}
long v = getBitValueAsLong(columnID, m);
return bitOr ? (v != 0L) : (v == m);
}
@Override
public final boolean testBitValue(String column,Number mask, boolean bitOr) {
return testBitValue(metaData.columnIDOf(column), mask, bitOr);
}
@SuppressWarnings({ "unchecked" })
private long getBitValueAsLong(int columnID,Number mask) {
Object o = getValue(columnID);
long m = asUnsignedLongChecked(mask);
long v = 0L;
if(null != o ) {
if(!INTERGRAL_CLASSES.contains(o.getClass())) {
throw new UnsupportedOperationException(
"UNSUPPORTED bit operation for column '"+metaData.columnNameOf(columnID)+"'");
}
v = COLUMN_TRANSFORMER.to(o,(Class