package jef.tools.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* 使用Unsafe的字段反射程序
* @author Administrator
*
*/
@SuppressWarnings("restriction")
public abstract class FieldAccessor {
public abstract Object getObject(Object bean);
public abstract void set(Object bean, Object value);
protected abstract Class<?> getType();
protected long offset;
protected Object staticBase;
final static class I extends FieldAccessor{
public Object getObject(Object bean) {
return Integer.valueOf(UnsafeUtils.unsafe.getInt(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putInt(staticBase==null?bean:staticBase,offset, ((Integer)value).intValue());
}
protected Class<?> getType() {
return int.class;
}
}
final static class S extends FieldAccessor{
public Object getObject(Object bean) {
return Short.valueOf(UnsafeUtils.unsafe.getShort(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putShort(staticBase==null?bean:staticBase,offset, ((Short)value).shortValue());
}
protected Class<?> getType() {
return short.class;
}
}
final static class F extends FieldAccessor{
public Object getObject(Object bean) {
return Float.valueOf(UnsafeUtils.unsafe.getFloat(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putFloat(staticBase==null?bean:staticBase,offset, ((Float)value).floatValue());
}
protected Class<?> getType() {
return float.class;
}
}
final static class B extends FieldAccessor{
public Object getObject(Object bean) {
return Byte.valueOf(UnsafeUtils.unsafe.getByte(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putByte(staticBase==null?bean:staticBase,offset, ((Byte)value).byteValue());
}
protected Class<?> getType() {
return byte.class;
}
}
final static class Z extends FieldAccessor{
public Object getObject(Object bean) {
return Boolean.valueOf(UnsafeUtils.unsafe.getBoolean(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putBoolean(staticBase==null?bean:staticBase,offset, ((Boolean)value).booleanValue());
}
protected Class<?> getType() {
return boolean.class;
}
}
final static class J extends FieldAccessor{
public Object getObject(Object bean) {
return Long.valueOf(UnsafeUtils.unsafe.getLong(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putLong(staticBase==null?bean:staticBase,offset, ((Long)value).longValue());
}
protected Class<?> getType() {
return long.class;
}
}
final static class D extends FieldAccessor{
public Object getObject(Object bean) {
return Double.valueOf(UnsafeUtils.unsafe.getDouble(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putDouble(staticBase==null?bean:staticBase,offset, ((Double)value).doubleValue());
}
protected Class<?> getType() {
return double.class;
}
}
final static class C extends FieldAccessor{
public Object getObject(Object bean) {
return Character.valueOf(UnsafeUtils.unsafe.getChar(staticBase==null?bean:staticBase,offset));
}
public void set(Object bean, Object value) {
if(value==null)return;
UnsafeUtils.unsafe.putDouble(staticBase==null?bean:staticBase,offset, ((Character)value).charValue());
}
protected Class<?> getType() {
return char.class;
}
}
final static class O extends FieldAccessor{
private Class<?> type;
O(Class<?> type){
this.type=type;
}
public Object getObject(Object bean) {
return UnsafeUtils.unsafe.getObject(staticBase==null?bean:staticBase,offset);
}
public void set(Object bean, Object value) {
UnsafeUtils.unsafe.putObject(staticBase==null?bean:staticBase, offset, value);
}
protected Class<?> getType() {
return type;
}
}
/**
* A safe field accessor (but slow)
* This will work on some JVM which doesn't support 'sun.misc.Unsafe'.
*/
final static class Safe extends FieldAccessor{
private Field field;
Safe(Field field){
this.field=field;
field.setAccessible(true);
}
public Object getObject(Object bean) {
try {
return field.get(bean);
} catch (Exception e) {
throw new IllegalArgumentException(field.getName()+" get error.",e);
}
}
public void set(Object bean, Object value) {
try {
field.set(bean, value);
} catch (Exception e) {
throw new IllegalArgumentException(field.getName()+" set error.",e);
}
}
protected Class<?> getType() {
return field.getType();
}
}
public static FieldAccessor generateAccessor(Field field) {
if(!UnsafeUtils.enable){
return new Safe(field);
}
FieldAccessor accessor;
Class<?> c=field.getType();
if(c==int.class){
accessor=new I();
}else if(c==long.class){
accessor=new J();
}else if(c==short.class){
accessor=new S();
}else if(c==float.class){
accessor=new F();
}else if(c==double.class){
accessor=new D();
}else if(c==char.class){
accessor=new C();
}else if(c==boolean.class){
accessor=new Z();
}else if(c==byte.class){
accessor=new B();
}else{
accessor=new O(field.getType());
}
try{
if(Modifier.isStatic(field.getModifiers())){
accessor.staticBase=UnsafeUtils.getUnsafe().staticFieldBase(field);
accessor.offset=UnsafeUtils.getUnsafe().staticFieldOffset(field);
}else{
accessor.offset=UnsafeUtils.getUnsafe().objectFieldOffset(field);
}
}catch(Exception e){
e.printStackTrace();
}
return accessor;
}
}