View Javadoc
1   /*
2    *  Copyright 2010, 2011, 2012 Christopher Pheby
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.jadira.usertype.bindings;
17  
18  import java.io.Serializable;
19  import java.lang.annotation.Annotation;
20  import java.lang.reflect.InvocationTargetException;
21  import java.sql.PreparedStatement;
22  import java.sql.ResultSet;
23  import java.sql.SQLException;
24  import java.util.Properties;
25  
26  import org.hibernate.HibernateException;
27  import org.hibernate.engine.spi.SharedSessionContractImplementor;
28  import org.hibernate.usertype.EnhancedUserType;
29  import org.hibernate.usertype.ParameterizedType;
30  import org.jadira.bindings.core.api.Binding;
31  import org.jadira.bindings.core.binder.BasicBinder;
32  import org.jadira.usertype.spi.shared.AbstractHeuristicUserType;
33  
34  /**
35   * Allows dynamic invocation of any class by mapping it using a binding type.
36   */
37  public class PersistentBoundClass extends AbstractHeuristicUserType implements ParameterizedType, EnhancedUserType, Serializable {
38  
39  	private static final long serialVersionUID = 3094384329334123541L;
40  	
41  	private static final BasicBinder BINDING = new BasicBinder();
42  	
43  	private Class<?> javaClass;
44  	
45  	private Class<? extends Annotation> qualifier;
46  
47  	@SuppressWarnings("rawtypes")
48  	private Binding binding;
49  	
50  	public void setParameterValues(Properties parameters) {
51  
52  		if (parameters.containsKey("javaClass")) {
53  			String mappedClassName = parameters.getProperty("javaClass");
54  			try {
55  				this.javaClass = Class.forName(mappedClassName);
56  			} catch (ClassNotFoundException e) {
57  				throw new HibernateException("Specified Java class could not be found", e);
58  			}
59  		}
60  		
61  		if (parameters.containsKey("hibernateClass")) {
62  			String mappedClassName = parameters.getProperty("hibernateClass");
63  			try {
64  				super.setIdentifierType((Class<?>) Class.forName(mappedClassName));
65  			} catch (ClassNotFoundException e) {
66  				throw new HibernateException("Specified Hibernate class could not be found", e);
67  			}
68  		}
69  		
70  		if (parameters.containsKey("qualifier")) {
71  			String mappedClassName = parameters.getProperty("qualifier");
72  			try {
73  				@SuppressWarnings("unchecked")
74  				final Class<? extends Annotation> myQualifier = ((Class<? extends Annotation>) Class.forName(mappedClassName));
75  				qualifier = myQualifier;
76  			} catch (ClassNotFoundException e) {
77  				throw new HibernateException("Specified Qualifier class could not be found", e);
78  			}
79  		}
80  
81  		if (javaClass == null) {
82  			throw new HibernateException("Java class was not defined");
83  		}
84  		if (super.getIdentifierType() == null) {
85  			throw new HibernateException("Hibernate class was not defined");
86  		}
87  		
88  		super.setParameterValues(parameters);
89  		
90  		binding = BINDING.findBinding(javaClass, getIdentifierType(), qualifier);
91  		
92  		if (binding == null) {
93  			throw new HibernateException("Could not resolve binding instance");
94  		}
95  	}
96  
97  	@Override
98  	public Class<?> returnedClass() {
99  		return javaClass;
100 	}
101 
102 	@Override
103 	public Object doNullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
104 
105 		Object identifier = getType().get(rs, names[0], session);
106 		
107 		if (rs.wasNull()) {
108 			return null;
109 		}
110 
111 		@SuppressWarnings("unchecked")
112 		final Object result = binding.unmarshal(identifier);
113 		return result;
114 	}
115 
116     @Override
117     public void doNullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
118 
119     	if (value == null) {
120 			preparedStatement.setNull(index, getType().sqlType());
121 		} else {
122 			
123 			@SuppressWarnings("unchecked")
124 			final Object identifier = binding.marshal(value);
125 			getType().nullSafeSet(preparedStatement, identifier, index, session);
126 		}
127     }
128 }