org.h2.value.ValueJavaObject Maven / Gradle / Ivy
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.value;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import org.h2.engine.SysProperties;
import org.h2.store.DataHandler;
import org.h2.util.JdbcUtils;
import org.h2.util.Utils;
/**
* Implementation of the OBJECT data type.
*/
public class ValueJavaObject extends ValueBytes {
private static final ValueJavaObject EMPTY =
new ValueJavaObject(Utils.EMPTY_BYTES, null);
private final DataHandler dataHandler;
protected ValueJavaObject(byte[] v, DataHandler dataHandler) {
super(v);
this.dataHandler = dataHandler;
}
/**
* Get or create a java object value for the given byte array.
* Do not clone the data.
*
* @param javaObject the object
* @param b the byte array
* @param dataHandler provides the object serializer
* @return the value
*/
public static ValueJavaObject getNoCopy(Object javaObject, byte[] b,
DataHandler dataHandler) {
if (b != null && b.length == 0) {
return EMPTY;
}
ValueJavaObject obj;
if (SysProperties.serializeJavaObject) {
if (b == null) {
b = JdbcUtils.serialize(javaObject, dataHandler);
}
obj = new ValueJavaObject(b, dataHandler);
} else {
obj = new NotSerialized(javaObject, b, dataHandler);
}
if (b == null || b.length > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) {
return obj;
}
return (ValueJavaObject) Value.cache(obj);
}
@Override
public int getType() {
return Value.JAVA_OBJECT;
}
@Override
public void set(PreparedStatement prep, int parameterIndex)
throws SQLException {
Object obj = JdbcUtils.deserialize(getBytesNoCopy(), getDataHandler());
prep.setObject(parameterIndex, obj, Types.JAVA_OBJECT);
}
/**
* Value which serializes java object only for I/O operations.
* Used when property {@link SysProperties#serializeJavaObject} is disabled.
*
* @author Sergi Vladykin
*/
private static class NotSerialized extends ValueJavaObject {
private Object javaObject;
private int displaySize = -1;
NotSerialized(Object javaObject, byte[] v, DataHandler dataHandler) {
super(v, dataHandler);
this.javaObject = javaObject;
}
@Override
public void set(PreparedStatement prep, int parameterIndex)
throws SQLException {
prep.setObject(parameterIndex, getObject(), Types.JAVA_OBJECT);
}
@Override
public byte[] getBytesNoCopy() {
if (value == null) {
value = JdbcUtils.serialize(javaObject, null);
}
return value;
}
@Override
protected int compareSecure(Value v, CompareMode mode) {
Object o1 = getObject();
Object o2 = v.getObject();
boolean o1Comparable = o1 instanceof Comparable;
boolean o2Comparable = o2 instanceof Comparable;
if (o1Comparable && o2Comparable &&
Utils.haveCommonComparableSuperclass(o1.getClass(), o2.getClass())) {
@SuppressWarnings("unchecked")
Comparable