1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.jadira.usertype.spi.shared;
17  
18  import static org.jadira.usertype.spi.utils.reflection.ArrayUtils.copyOf;
19  
20  import java.io.Serializable;
21  import java.lang.reflect.InvocationTargetException;
22  import java.sql.PreparedStatement;
23  import java.sql.ResultSet;
24  import java.sql.SQLException;
25  import java.util.Properties;
26  
27  import org.hibernate.HibernateException;
28  import org.hibernate.engine.spi.SharedSessionContractImplementor;
29  import org.hibernate.type.AbstractSingleColumnStandardBasicType;
30  import org.hibernate.type.TypeResolver;
31  import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
32  import org.hibernate.usertype.EnhancedUserType;
33  
34  public abstract class AbstractHeuristicUserType extends AbstractUserType implements EnhancedUserType, Serializable {
35  
36  	private static final long serialVersionUID = 7099384329368123541L;
37  
38  	private Class<?> identifierType;
39  	
40  	private AbstractSingleColumnStandardBasicType<?> type;
41  	
42  	private int[] sqlTypes;
43  
44      protected void setIdentifierType(Class<?> identifierType) {
45      	this.identifierType = identifierType;
46      }
47      
48      protected Class<?> getIdentifierType() {
49      	return identifierType;
50      }
51      
52      protected AbstractSingleColumnStandardBasicType<?> getType() {
53      	return type;
54      }
55      
56  	public void setParameterValues(Properties parameters) {
57  		
58  		@SuppressWarnings("unchecked")
59  		final AbstractSingleColumnStandardBasicType<? extends Object> heuristicType = (AbstractSingleColumnStandardBasicType<? extends Object>) new TypeResolver().heuristicType(identifierType.getName(), parameters);
60  		if (heuristicType == null) {
61  			throw new HibernateException("Unsupported identifier type " + identifierType.getName());
62  		}
63  		
64  		type = heuristicType;
65  		sqlTypes = new int[]{ type.sqlType() };
66  	}
67  
68  	public int[] sqlTypes() {
69          return copyOf(sqlTypes);
70      }
71  
72      @Override
73      public abstract Class<?> returnedClass();
74      
75  	@Override
76  	public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
77  
78  		beforeNullSafeOperation(session);
79  		
80  		try {
81  	
82  			try {
83  				return doNullSafeGet(rs, names, session, owner);
84  			} catch (IllegalArgumentException e) {
85  				throw new HibernateException(
86  						"Exception during nullSafeGet of type '" 
87  							+ identifierType.getName() + "'", e);
88  			} catch (IllegalAccessException e) {
89  				throw new HibernateException(
90  						"Exception during nullSafeGet of type '" 
91  								+ identifierType.getName() + "'", e);
92  			} catch (InvocationTargetException e) {
93  				throw new HibernateException(
94  						"Exception during nullSafeGet of type '" 
95  								+ identifierType.getName() + "'", e);
96  			}    
97      	} finally {
98      		afterNullSafeOperation(session);
99      	}
100 	}
101 
102     public abstract Object doNullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException;
103     
104     @Override
105     public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
106 
107     	beforeNullSafeOperation(session);
108     	
109     	try {
110     		doNullSafeSet(preparedStatement, value, index, session);
111 		} catch (IllegalArgumentException e) {
112 			throw new HibernateException(
113 					"Exception during nullSafeSet of type '" 
114 							+ identifierType.getName() + "'", e);
115 		} catch (IllegalAccessException e) {
116 			throw new HibernateException(
117 					"Exception during nullSafeSet of type '" 
118 							+ identifierType.getName() + "'", e);
119 			} catch (InvocationTargetException e) {
120 		} finally {
121 			afterNullSafeOperation(session);
122 		}
123     }
124 
125     public abstract void doNullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException;
126 
127     @SuppressWarnings({ "rawtypes", "unchecked" })
128     @Override
129     public String objectToSQLString(Object object) {
130     	final JavaTypeDescriptor desc = type.getJavaTypeDescriptor();
131     	return desc.toString(object);
132     }
133 
134     @SuppressWarnings({ "rawtypes", "unchecked" })
135 	@Override
136 	@Deprecated
137     public String toXMLString(Object object) {
138     	final JavaTypeDescriptor desc = type.getJavaTypeDescriptor();
139     	return desc.toString(object);
140     }
141 
142     @Override
143     @Deprecated
144     public Object fromXMLString(String string) {
145 		return type.fromString(string);
146     }
147 }