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

com.heliorm.sql.UnsafePojoOperations Maven / Gradle / Ivy

The newest version!
package com.heliorm.sql;

import com.heliorm.OrmException;
import sun.misc.Unsafe;

import static java.lang.String.format;

/**
 * An implementation of PojoOperations that uses the sun.misc.Unsafe API to
 * manipulate POJOs without the need for a lot of reflection or adherence to
 * specific conventions. This allows the user to write their POJOs the way they
 * want to reflect their application logic without caring about ceremony.
 * Default constructors and getters and setters are not required.
 * 

* This is however using an internal Java API with an unclear future, so users * who worry about this can implement PojoOperations in different and safer * ways. * * @author gideon */ final class UnsafePojoOperations extends AbstractPojoOperations { private final Unsafe unsafe; UnsafePojoOperations() throws OrmException { super(); unsafe = getUnsafe(); } /** * Get hold of the sun.misc.Unsafe object to use for object manipulation. * * @return The Unsafe object * @throws OrmException Thrown if there is an error while getting the Unsafe * object */ private static Unsafe getUnsafe() throws OrmException { try { java.lang.reflect.Field f = Unsafe.class .getDeclaredField("theUnsafe"); f.setAccessible(true); return (Unsafe) f.get(null); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { throw new OrmException(format("Error getting Unsafe (%s)", ex.getMessage()), ex); } } /** * Get the value for the given field from the given object and return either * a boolean or a Boolean object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getBoolean(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getBoolean(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * a long or a Long object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getLong(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getLong(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * an int or an Integer object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getInteger(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getInt(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * a short or a Short object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getShort(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getShort(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * a byte or a Byte object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getByte(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getByte(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * a double or a Double object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getDouble(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getDouble(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * a float or a Float object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getFloat(Object pojo, java.lang.reflect.Field field) { if (field.getType().isPrimitive()) { return unsafe.getFloat(pojo, unsafe.objectFieldOffset(field)); } return getObject(pojo, field); } /** * Get the value for the given field from the given object and return either * an enum value. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The result */ protected Object getEnum(Object pojo, java.lang.reflect.Field field) throws OrmException { Object value = getObject(pojo, field); if (value != null) { Class valueClass = value.getClass(); if (valueClass.isEnum()) { return ((Enum) value).name(); } throw new OrmException(format("Cannot read Pojo enum field from data of type %s", valueClass.getSimpleName())); } return null; } /** * Convenience method to retrieve the value of a field from an object. * * @param pojo The object to get data from * @param field The field for which to get the data * @return The data */ protected Object getObject(Object pojo, java.lang.reflect.Field field) { return unsafe.getObject(pojo, unsafe.objectFieldOffset(field)); } /** * Set the value for the given field on the given object to the supplied * boolean value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setBoolean(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putBoolean(pojo, unsafe.objectFieldOffset(field), (boolean) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * long value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setLong(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putLong(pojo, unsafe.objectFieldOffset(field), (long) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * integer value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setInteger(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putInt(pojo, unsafe.objectFieldOffset(field), (int) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * short value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setShort(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putShort(pojo, unsafe.objectFieldOffset(field), (short) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * byte value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setByte(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putByte(pojo, unsafe.objectFieldOffset(field), (byte) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * double value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setDouble(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putDouble(pojo, unsafe.objectFieldOffset(field), (double) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * float value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setFloat(Object pojo, java.lang.reflect.Field field, Object value) { if (field.getType().isPrimitive()) { unsafe.putFloat(pojo, unsafe.objectFieldOffset(field), (float) value); } else { setObject(pojo, field, value); } } /** * Set the value for the given field on the given object to the supplied * enum value. * * @param pojo The object on which to set the data * @param field The field for which to set the data * @param value The value to set */ protected void setEnum(Object pojo, java.lang.reflect.Field field, Object value) throws OrmException { if (value != null) { Class valueClass = value.getClass(); if (valueClass.isEnum()) { unsafe.putObject(pojo, unsafe.objectFieldOffset(field), value); } else { if (!String.class.isAssignableFrom(valueClass)) { throw new OrmException(format("Cannot update Pojo enum field from data of type %s", valueClass.getSimpleName())); } Class fieldClass = field.getType(); if (!fieldClass.isEnum()) { throw new OrmException(format("Field '%s' on %s is supposed to be an emum type. BUG!", field.getName(), field.getDeclaringClass().getSimpleName())); } unsafe.putObject(pojo, unsafe.objectFieldOffset(field), Enum.valueOf((Class) fieldClass, (String) value)); } } } /** * Convenience method to set the value supplied for the given field on the * given object. * * @param pojo The object on which to set the value * @param field The field for which to set the value * @param value The value */ protected void setObject(Object pojo, java.lang.reflect.Field field, Object value) { unsafe.putObject(pojo, unsafe.objectFieldOffset(field), value); } @Override protected O newPojoInstance(Class type) throws OrmException { try { return (O) unsafe.allocateInstance(type); } catch (InstantiationException ex) { throw new OrmException(ex.getMessage(), ex); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy