/*
* Copyright 2010, 2011, 2012 Christopher Pheby
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jadira.usertype.spi.shared;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.EnhancedUserType;
import org.jadira.usertype.spi.utils.reflection.TypeHelper;
public abstract class AbstractReflectionUserType<T> extends AbstractKnownClassHeuristicUserType<T> implements EnhancedUserType, Serializable {
private static final long serialVersionUID = 7943328235820102665L;
private Method identifierMethod;
private Method valueOfMethod;
protected void setIdentifierMethod(Method identifierMethod) {
this.identifierMethod = identifierMethod;
}
protected Method getIdentifierMethod() {
return identifierMethod;
}
protected void setValueOfMethod(Method valueOfMethod) {
if (!Modifier.isStatic(valueOfMethod.getModifiers())) {
throw new IllegalStateException("valueOfMethod must be static: " + valueOfMethod.toString());
}
this.valueOfMethod = valueOfMethod;
}
protected Method getValueOfMethod() {
return valueOfMethod;
}
public void setParameterValues(Properties parameters) {
if (identifierMethod == null) {
throw new IllegalStateException("No identifier method was defined for " + this.getClass().getName());
}
setIdentifierType(identifierMethod.getReturnType());
super.setParameterValues(parameters);
}
@SuppressWarnings("unchecked")
@Override
public Class<T> returnedClass() {
return (Class<T>) TypeHelper.getTypeArguments(AbstractReflectionUserType.class, getClass()).get(0);
}
@Override
public Object doNullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Object identifier = getType().get(rs, names[0], session);
if (rs.wasNull()) {
return null;
}
return valueOfMethod.invoke(getMappedClass(), new Object[] { identifier });
}
@Override
public void doNullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (value == null) {
preparedStatement.setNull(index, getType().sqlType());
} else {
Object identifier = identifierMethod.invoke(value, new Object[0]);
getType().nullSafeSet(preparedStatement, identifier, index, session);
}
}
@Override
public String objectToSQLString(final Object object) {
if (object == null) {
return null;
}
if (identifierMethod != null) {
try {
return String.valueOf(identifierMethod.invoke(object));
} catch (InvocationTargetException e) {
// Ignore
} catch (IllegalAccessException e) {
// Ignore
}
}
return super.objectToSQLString(object);
}
@Override
public String toXMLString(Object object) {
if (identifierMethod != null) {
try {
return String.valueOf(identifierMethod.invoke(object));
} catch (InvocationTargetException e) {
throw new HibernateException("Problem constructing XMLString: " + object + "'", e);
} catch (IllegalAccessException e) {
throw new HibernateException("Problem constructing XMLString: " + object + "'", e);
}
}
return super.toXMLString(object);
}
}