/********************************************************************
 * Copyright © 2006 VHA. All rights reserved
 ********************************************************************/


package gov.va.med.fw.persistent.hibernate;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.HibernateException;
import org.hibernate.type.StringType;
import org.hibernate.usertype.UserType;

import gov.va.med.fw.model.lookup.Lookup;
import gov.va.med.fw.model.lookup.SimpleLookupUtils;

/**
 * Initial javadoc for class AbstractSimpleLookupUserType.
 * TODO - Add content here
 * 
 * Created Sep 29, 2006 12:53:18 PM
 * @author DNS   BOHMEG
 */
public abstract class AbstractSimpleLookupUserType implements UserType {
    
    private final StringType stringType;
    
    public AbstractSimpleLookupUserType () {
    	super();
    	stringType = new StringType ();
    }
   
	public final Object assemble(Serializable cached, Object owener)
			throws HibernateException {
		return cached;
	}
	
	public final Object deepCopy(Object value) throws HibernateException {
		return value;
	}
	
	public final Serializable disassemble(Object value) throws HibernateException {
		return (Serializable)value;
	}
	
	public final boolean equals(Object x, Object y) throws HibernateException {
		return ((x == y) || ((x != null) && x.equals(y)));
	}
	
	public final int hashCode(Object x) throws HibernateException {
		return x != null ? x.hashCode() : 0;
	}
	
	public final boolean isMutable() {
		return false;
	}
	
	public final Object nullSafeGet(ResultSet rs, String[] names, Object owner)
			throws HibernateException, SQLException {
        String string = (String)this.stringType.nullSafeGet(rs, names[0]);
        
        try {
        	return SimpleLookupUtils.getByCode(returnedClass(), string);
        } catch (ClassNotFoundException e) {
        	throw new HibernateException(e);
        }
	}
	
	public void nullSafeSet(PreparedStatement st, Object value, int index)
			throws HibernateException, SQLException {
        String string = null;
        if (value instanceof Lookup)
        	string = ((Lookup) value).getCode();
        else if (value instanceof String)
        	string = (String) value;
        this.stringType.nullSafeSet(st, string, index);	
    }
	
	public final Object replace(Object original, Object target, Object owner)
			throws HibernateException {
		return original;
	}
	
	public abstract Class returnedClass();
	
	public final int[] sqlTypes() {
		return new int[] { this.stringType.sqlType() };
	}

}
