Package org.sql2o.reflection

Source Code of org.sql2o.reflection.UnsafeFieldGetterFactory

package org.sql2o.reflection;

import org.sql2o.Sql2oException;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
* @author mdelapenya
*/
@SuppressWarnings("Unsafe")
public class UnsafeFieldGetterFactory implements FieldGetterFactory, ObjectConstructorFactory {
    private final static Unsafe theUnsafe;
    static {
        try {
            Class unsafeClass = Class.forName("sun.misc.Unsafe");
            Field declaredField = unsafeClass.getDeclaredField("theUnsafe");
            declaredField.setAccessible(true);
            theUnsafe = (Unsafe) declaredField.get(null);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    public Getter newGetter(final Field field) {
        final Class type = field.getType();
        final boolean isStatic = Modifier.isStatic(field.getModifiers());

        final long offset =  isStatic
                ? theUnsafe.staticFieldOffset(field)
                : theUnsafe.objectFieldOffset(field);

        if (!Modifier.isVolatile(field.getModifiers())) {
            if (type == Boolean.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getBoolean(obj, offset);
                    }

                    public Class getType() {
                        return Boolean.TYPE;
                    }
                };
            }

            if (type == Character.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getChar(obj, offset);
                    }

                    public Class getType() {
                        return Character.TYPE;
                    }
                };
            }

            if (type == Byte.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getByte(obj, offset);
                    }

                    public Class getType() {
                        return Byte.TYPE;
                    }
                };
            }

            if (type == Short.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getShort(obj, offset);
                    }

                    public Class getType() {
                        return Short.TYPE;
                    }
                };
            }

            if (type == Integer.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getInt(obj, offset);
                    }

                    public Class getType() {
                        return Integer.TYPE;
                    }
                };
            }

            if (type == Long.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getLong(obj, offset);
                    }

                    public Class getType() {
                        return Long.TYPE;
                    }
                };
            }

            if (type == Float.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getFloat(obj, offset);
                    }

                    public Class getType() {
                        return Float.TYPE;
                    }
                };
            }
            if (type == Double.TYPE) {
                return new Getter() {
                    public Object getProperty(Object obj) {
                        return theUnsafe.getDouble(obj, offset);
                    }

                    public Class getType() {
                        return Double.TYPE;
                    }
                };
            }
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getObject(obj, offset);
                }

                public Class getType() {
                    return type;
                }
            };
        }

        if (type == Boolean.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getBooleanVolatile(obj, offset);
                }

                public Class getType() {
                    return Boolean.TYPE;
                }
            };
        }
        if (type == Character.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getCharVolatile(obj, offset);
                }

                public Class getType() {
                    return Character.TYPE;
                }
            };
        }
        if (type == Byte.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getByteVolatile(obj, offset);
                }

                public Class getType() {
                    return Byte.TYPE;
                }
            };
        }
        if (type == Short.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getShortVolatile(obj, offset);
                }

                public Class getType() {
                    return Short.TYPE;
                }
            };
        }
        if (type == Integer.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getIntVolatile(obj, offset);
                }

                public Class getType() {
                    return Integer.TYPE;
                }
            };
        }
        if (type == Long.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getLongVolatile(obj, offset);
                }

                public Class getType() {
                    return Long.TYPE;
                }
            };
        }
        if (type == Float.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getFloatVolatile(obj, offset);
                }

                public Class getType() {
                    return Float.TYPE;
                }
            };
        }
        if (type == Double.TYPE) {
            return new Getter() {
                public Object getProperty(Object obj) {
                    return theUnsafe.getDoubleVolatile(obj, offset);
                }

                public Class getType() {
                    return Double.TYPE;
                }
            };
        }
        return new Getter() {
            public Object getProperty(Object obj) {
                return theUnsafe.getObjectVolatile(obj, offset);
            }

            public Class getType() {
                return type;
            }
        };
    }

    public ObjectConstructor newConstructor(final Class<?> clazz) {
        return getConstructor(clazz);
    }
    public static ObjectConstructor getConstructor(final Class<?> clazz) {
        return new ObjectConstructor() {
            public Object newInstance() {
                try {
                    return theUnsafe.allocateInstance(clazz);
                } catch (InstantiationException e) {
                    throw new Sql2oException("Could not create a new instance of class " + clazz, e);
                }
            }
        };
    }
}
TOP

Related Classes of org.sql2o.reflection.UnsafeFieldGetterFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.