All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gu.sql2java.BeanConverter Maven / Gradle / Ivy

There is a newer version: 5.3.2
Show newest version
package gu.sql2java;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import com.google.common.primitives.Primitives;

/**
 * implementation of {@link IBeanConverter} by reflect
* generic type converter between L and R
* @author guyadong * @param left type extends BaseBean * @param right type * */ public class BeanConverter extends IBeanConverter.AbstractHandle implements Constant{ static final String GET_INITIALIZED = "getInitialized"; static final String SET_INITIALIZED = "setInitialized"; static final String GET_MODIFIED = "getModified"; static final String SET_MODIFIED = "setModified"; static final String SET_NEW = "setNew"; static final String IS_NEW = "isNew"; private final Map methods = new Hashtable(); private final Map rightIndexs = new Hashtable(); private final Map> setterParams = new Hashtable>(); private final RowMetaData metaData; private boolean bitCheck(String name,int...bits){ Integer id = rightIndexs.get(name); return (null == id)?false:bitCheck(id.intValue(),bits); } private int[] bitOR(String name,int... bits){ return bitOR(rightIndexs.get(name),bits); } private void getGetter(String name){ try{ methods.put(name,rightType.getMethod(name)); }catch(NoSuchMethodException e){} } private void getSetter(String name, Class...types) throws NoSuchMethodException{ for(ClassparamType:types){ try{ methods.put(name,rightType.getMethod(name,paramType)); setterParams.put(name, paramType); return; }catch(NoSuchMethodException e){ continue; } } throw new NoSuchMethodException(); } private void getSetterNoThrow(String name, Class...types){ try{ getSetter(name,types); }catch(NoSuchMethodException e){} } /** * constructor * @param leftClass * @param rightClass * @param javaFields a comma splice string,including all field name of R,
* if null or empty, use default string:{@link RowMetaData#columnJavaNames} */ public BeanConverter (Class leftClass, Class rightClass,String javaFields){ super(leftClass,rightClass); this.metaData = RowMetaData.getMetaData(leftClass); init(javaFields); } /** @see #BeanConverter(Class,Class,String) */ public BeanConverter (Class leftClass, Class rightClass){ this(leftClass,rightClass,null); } private void init(String javaFields){ ListrightFields; if(null == javaFields || javaFields.isEmpty()){ rightFields = metaData.columnJavaNames; }else{ rightFields = Arrays.asList(javaFields.split(",")); } for(int i = 0 ; i < rightFields.size(); ++i){ String field = rightFields.get(i).trim(); if(!field.matches("\\w+")){ throw new IllegalArgumentException("invalid 'javaFields':" + javaFields); } rightIndexs.put(field,i); } try{ methods.put(IS_NEW,rightType.getMethod(IS_NEW)); methods.put(GET_INITIALIZED,rightType.getMethod(GET_INITIALIZED)); getSetter(SET_NEW,boolean.class); if(rightIndexs.size() > STATE_BIT_NUM){ getSetter(SET_INITIALIZED,int[].class,List.class); }else{ getSetter(SET_INITIALIZED,int.class); } getGetter(GET_MODIFIED); if(rightIndexs.size() > STATE_BIT_NUM){ getSetter(SET_MODIFIED,int[].class,List.class); }else{ getSetter(SET_MODIFIED,int.class); } }catch(NoSuchMethodException e){ throw new RuntimeException(e); } for(int i =0; i type = setter.getParameterTypes()[0]; if(type.isPrimitive()){ if(Date.class.isAssignableFrom(type)){ getSetterNoThrow(setter.getName(),type,long.class); } else{ getSetterNoThrow(setter.getName(),type,Primitives.unwrap(type)); } }else if(ByteBuffer.class.isAssignableFrom(type) || byte[].class.isAssignableFrom(type)){ getSetterNoThrow(setter.getName(),type,ByteBuffer.class,byte[].class); } else { getSetterNoThrow(setter.getName(),type); } } } @Override protected void doFromRight(L left, R right) { try{ Method getterMethod; left.resetIsModified(); int selfModified = 0; int[] initialized; int[] modified; if(rightIndexs.size() > STATE_BIT_NUM){ initialized = (int[])methods.get(GET_INITIALIZED).invoke(right); modified = (int[])methods.get(GET_MODIFIED).invoke(right); }else{ initialized = new int[]{(Integer)methods.get(GET_INITIALIZED).invoke(right)}; modified = new int[]{(Integer)methods.get(GET_MODIFIED).invoke(right)}; } for(int columnId = 0; columnId < metaData.columnCount; ++columnId){ String columnName = metaData.columnNameOf(columnId); if(bitCheck(columnName,initialized)){ String getterName = metaData.getterMethods.get(columnId).getName(); if(null != (getterMethod = methods.get(getterName))){ left.setValue(columnId, getterMethod.invoke(right)); if(bitCheck(columnName,modified)){ selfModified |= (1<>STATE_BIT_SHIFT]; int[] modified = new int[(rightIndexs.size() + STATE_BIT_NUM - 1)>>STATE_BIT_SHIFT]; Arrays.fill(initialized, 0); Arrays.fill(modified, 0); for(int columnId = 0; columnId < metaData.columnCount; ++columnId){ String columnName = metaData.columnNameOf(columnId); String setterName = metaData.setterMethods.get(columnId).getName(); if(null != (setterMethod = methods.get(setterName)) && left.isInitialized(columnId)){ try{ setterMethod.invoke(right,cast(setterParams.get(setterName),left.getValue(columnId))); bitOR(columnName,initialized); if(left.isModified(columnId)){ bitOR(columnName,modified); } }catch(NullCastPrimitiveException e){} } } // IGNORE field fl_device.create_time , controlled by 'general.beanconverter.tonative.ignore' in properties file /* if(null != (setterMethod = methods.get(Column.createTime.setter)) && left.checkCreateTimeInitialized()){ try{ setterMethod.invoke(right,cast(setterParams.get(Column.createTime.setter),left.getCreateTime())); bitOR(Column.createTime.name(),initialized); if(left.checkCreateTimeModified()){ bitOR(Column.createTime.name(),modified); } }catch(NullCastPrimitiveException e){} } */ // IGNORE field fl_device.update_time , controlled by 'general.beanconverter.tonative.ignore' in properties file /* if(null != (setterMethod = methods.get(Column.updateTime.setter)) && left.checkUpdateTimeInitialized()){ try{ setterMethod.invoke(right,cast(setterParams.get(Column.updateTime.setter),left.getUpdateTime())); bitOR(Column.updateTime.name(),initialized); if(left.checkUpdateTimeModified()){ bitOR(Column.updateTime.name(),modified); } }catch(NullCastPrimitiveException e){} } */ if(null != (setterMethod = methods.get(SET_MODIFIED))){ if( initialized.length > 1){ setterMethod.invoke(right,cast(setterParams.get(SET_MODIFIED),initialized)); }else{ setterMethod.invoke(right,initialized[0]); } } methods.get(SET_NEW).invoke(right,left.isNew()); if( initialized.length > 1){ methods.get(SET_INITIALIZED).invoke(right,cast(setterParams.get(SET_INITIALIZED),initialized)); methods.get(SET_MODIFIED).invoke(right,cast(setterParams.get(SET_MODIFIED),modified)); }else{ methods.get(SET_INITIALIZED).invoke(right,initialized[0]); methods.get(SET_MODIFIED).invoke(right,modified[0]); } }catch(RuntimeException e){ throw e; }catch(Exception e){ throw new RuntimeException(e); } } private static final List toList(long[] array) { ArrayList result = new ArrayList(array.length); for (int i = 0; i < array.length; i++) { result.add(new Long(array[i])); } return result; } private static final long[] toPrimitive(List list) { long[] dst = new long[list.size()]; Long element; for (int i = 0; i < dst.length; i++) { if(null == (element = list.get(i))){ throw new IllegalArgumentException("can't cast List to long[] because of null element"); } dst[i] = element.longValue(); } return dst; } /** * {@code source}转为{@code type}指定的类型 * @param type destination type * @param source source object * @return T instance */ @SuppressWarnings({ "unchecked" }) static final T cast(Class type,Object source){ try{ if(null ==source && type.isPrimitive()){ throw new NullCastPrimitiveException(String.format("can't convert null to primitive type %s",type.getSimpleName())); } return (T) source; }catch(ClassCastException cce){ // long[] -> List if(List.class.isAssignableFrom(type) && null != source && source instanceof long[]){ return (T) toList((long[]) source); } // List -> long[] if(long[].class == type && null != source && source instanceof List){ return (T) toPrimitive( (List) source); } // Long -> Date if(java.util.Date.class.isAssignableFrom(type) && null != source && source instanceof Long){ try { // call constructor,such as java.util.Date#Date(long), java.sql.Time.Time(long) return type.getConstructor(long.class).newInstance(source); } catch (Exception e) { StringWriter writer = new StringWriter(); e.printStackTrace(new PrintWriter(writer)); throw new ClassCastException(writer.toString()); } } // Date -> Long,long if( long.class == type || Long.class == type){ if(null != source && source instanceof java.util.Date){ Long time = ((java.util.Date)source).getTime(); return (T)time; } } // byte[] -> ByteBuffer if(ByteBuffer.class == type && null != source && source instanceof byte[]){ return (T) ByteBuffer.wrap((byte[]) source); } // ByteBuffer -> byte[] if(byte[].class == type && null != source && source instanceof ByteBuffer){ return (T) Sql2javaSupport.getBytesInBuffer((ByteBuffer) source); } throw cce; } } static final boolean bitCheck(int index,int...bits){ return 0 != (bits[index>>STATE_BIT_SHIFT]&(1<<(index&0x1f))); } static final int[] bitOR(int index,int... bits){ bits[index>>STATE_BIT_SHIFT] |= (1<<(index&0x1f)); return bits; } private static class NullCastPrimitiveException extends ClassCastException { private static final long serialVersionUID = 1L; NullCastPrimitiveException(String message) { super(message); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy