/jaxrs/eagledns/src/main/java/se/unlogic/standardutils/dao/DefaultManyToOneRelation.java

https://bitbucket.org/cprenzberg/resteasy · Java · 310 lines · 171 code · 95 blank · 44 comment · 27 complexity · 587104a64152d5a8e452fca4318f8a40 MD5 · raw file

  1. /*******************************************************************************
  2. * Copyright (c) 2010 Robert "Unlogic" Olofsson (unlogic@unlogic.se).
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the GNU Lesser Public License v3
  5. * which accompanies this distribution, and is available at
  6. * http://www.gnu.org/licenses/lgpl-3.0-standalone.html
  7. ******************************************************************************/
  8. package se.unlogic.standardutils.dao;
  9. import se.unlogic.standardutils.annotations.UnsupportedFieldTypeException;
  10. import se.unlogic.standardutils.dao.annotations.DAOManaged;
  11. import se.unlogic.standardutils.dao.annotations.ManyToOne;
  12. import se.unlogic.standardutils.populators.BeanStringPopulator;
  13. import se.unlogic.standardutils.populators.BeanStringPopulatorRegistery;
  14. import se.unlogic.standardutils.populators.QueryParameterPopulator;
  15. import se.unlogic.standardutils.reflection.ReflectionUtils;
  16. import se.unlogic.standardutils.string.StringUtils;
  17. import java.lang.reflect.Field;
  18. import java.lang.reflect.Method;
  19. import java.sql.Connection;
  20. import java.sql.ResultSet;
  21. import java.sql.SQLException;
  22. public class DefaultManyToOneRelation<LocalType,RemoteType, RemoteKeyType> implements ManyToOneRelation<LocalType, RemoteType, RemoteKeyType>{
  23. private final String columnName;
  24. private final Field field;
  25. private QueryParameterPopulator<RemoteKeyType> queryParameterPopulator;
  26. private Method queryMethod;
  27. private final BeanResultSetPopulator<RemoteKeyType> remoteKeyPopulator;
  28. private final Field remoteKeyField;
  29. private final AnnotatedDAOFactory daoFactory;
  30. private AnnotatedDAO<RemoteType> annotatedDAO;
  31. private QueryParameterFactory<RemoteType,RemoteKeyType> queryParameterFactory;
  32. private final Class<RemoteType> remoteClass;
  33. private final Class<RemoteKeyType> remoteRemoteKeyClass;
  34. private boolean initialized;
  35. public DefaultManyToOneRelation(Class<LocalType> beanClass, Class<RemoteType> remoteClass, Class<RemoteKeyType> remoteKeyClass, Field field, Field remoteKeyField, DAOManaged daoManaged, AnnotatedDAOFactory daoFactory) {
  36. this.remoteClass = remoteClass;
  37. this.remoteRemoteKeyClass = remoteKeyClass;
  38. this.field = field;
  39. this.remoteKeyField = remoteKeyField;
  40. this.daoFactory = daoFactory;
  41. if(!StringUtils.isEmpty(daoManaged.columnName())){
  42. this.columnName = daoManaged.columnName();
  43. }else{
  44. this.columnName = field.getName();
  45. }
  46. ReflectionUtils.fixFieldAccess(remoteKeyField);
  47. //TODO use column instead! somehow...
  48. Method resultSetMethod = ResultSetMethods.getColumnNameMethod(remoteKeyClass);
  49. if(resultSetMethod != null){
  50. remoteKeyPopulator = new MethodBasedResultSetPopulator<RemoteKeyType>(resultSetMethod, columnName);
  51. }else{
  52. BeanStringPopulator<RemoteKeyType> typePopulator = BeanStringPopulatorRegistery.getBeanStringPopulator(remoteKeyClass);
  53. if(typePopulator != null){
  54. remoteKeyPopulator = new TypeBasedResultSetPopulator<RemoteKeyType>(typePopulator, columnName);
  55. }else{
  56. throw new UnsupportedFieldTypeException("Unable to find resultset method or type populator for field " + remoteKeyField.getName() + " in " + remoteClass + " when creating many to one relation for field " + field.getName() + " in " + beanClass, field, ManyToOne.class, beanClass);
  57. }
  58. }
  59. }
  60. /* (non-Javadoc)
  61. * @see se.unlogic.utils.dao.ManyToOneRelation#getColumnName()
  62. */
  63. public String getColumnName(){
  64. return columnName;
  65. }
  66. /* (non-Javadoc)
  67. * @see se.unlogic.utils.dao.ManyToOneRelation#getQueryParameterPopulator()
  68. */
  69. public QueryParameterPopulator<RemoteKeyType> getQueryParameterPopulator(){
  70. if(queryParameterPopulator == null && queryMethod == null){
  71. if(!initialized){
  72. this.init();
  73. }
  74. this.queryParameterPopulator = annotatedDAO.getQueryParameterPopulator(remoteRemoteKeyClass);
  75. }
  76. return queryParameterPopulator;
  77. }
  78. /* (non-Javadoc)
  79. * @see se.unlogic.utils.dao.ManyToOneRelation#getQueryMethod()
  80. */
  81. public Method getQueryMethod(){
  82. if(this.queryMethod == null){
  83. this.queryMethod = PreparedStatementQueryMethods.getObjectQueryMethod();
  84. }
  85. return queryMethod;
  86. }
  87. /* (non-Javadoc)
  88. * @see se.unlogic.utils.dao.ManyToOneRelation#getBeanValue(LocalType)
  89. */
  90. @SuppressWarnings("unchecked")
  91. public RemoteKeyType getBeanValue(LocalType bean){
  92. try {
  93. RemoteType subBean = (RemoteType) field.get(bean);
  94. if(subBean == null){
  95. return null;
  96. }
  97. return (RemoteKeyType)remoteKeyField.get(subBean);
  98. } catch (IllegalArgumentException e) {
  99. throw new RuntimeException(e);
  100. } catch (IllegalAccessException e) {
  101. throw new RuntimeException(e);
  102. }
  103. }
  104. /* (non-Javadoc)
  105. * @see se.unlogic.utils.dao.ManyToOneRelation#getParamValue(java.lang.Object)
  106. */
  107. @SuppressWarnings("unchecked")
  108. public RemoteKeyType getParamValue(Object bean) {
  109. try {
  110. if(bean == null){
  111. return null;
  112. }
  113. return (RemoteKeyType) remoteKeyField.get(bean);
  114. } catch (IllegalArgumentException e) {
  115. throw new RuntimeException(e);
  116. } catch (IllegalAccessException e) {
  117. throw new RuntimeException(e);
  118. }
  119. }
  120. /* (non-Javadoc)
  121. * @see se.unlogic.utils.dao.ManyToOneRelation#setValue(LocalType, java.sql.ResultSet, java.sql.Connection, java.lang.reflect.Field[])
  122. */
  123. public void getRemoteValue(LocalType bean, ResultSet resultSet, Connection connection, RelationQuery relationQuery) throws SQLException{
  124. try {
  125. if(!initialized){
  126. this.init();
  127. }
  128. RemoteKeyType keyValue = remoteKeyPopulator.populate(resultSet);
  129. if(keyValue != null){
  130. HighLevelQuery<RemoteType> query = new HighLevelQuery<RemoteType>();
  131. query.addParameter(queryParameterFactory.getParameter(keyValue));
  132. if(relationQuery != null){
  133. query.disableAutoRelations(relationQuery.isDisableAutoRelations());
  134. }
  135. query.addRelations(relationQuery);
  136. RemoteType remoteBeanInstance = annotatedDAO.get(query ,connection);
  137. this.getField().set(bean, remoteBeanInstance);
  138. }
  139. } catch (IllegalArgumentException e) {
  140. throw new RuntimeException(e);
  141. } catch (IllegalAccessException e) {
  142. throw new RuntimeException(e);
  143. }
  144. }
  145. /* (non-Javadoc)
  146. * @see se.unlogic.utils.dao.ManyToOneRelation#add(LocalType, java.sql.Connection, java.lang.reflect.Field)
  147. */
  148. @SuppressWarnings("unchecked")
  149. public void add(LocalType bean, Connection connection, RelationQuery relationQuery) throws SQLException{
  150. if(!initialized){
  151. this.init();
  152. }
  153. try {
  154. RemoteType remoteBean = (RemoteType) field.get(bean);
  155. if(remoteBean != null){
  156. this.annotatedDAO.add(remoteBean, connection, relationQuery);
  157. }
  158. } catch (IllegalArgumentException e) {
  159. throw new RuntimeException(e);
  160. } catch (IllegalAccessException e) {
  161. throw new RuntimeException(e);
  162. }
  163. }
  164. /* (non-Javadoc)
  165. * @see se.unlogic.utils.dao.ManyToOneRelation#update(LocalType, java.sql.Connection, java.lang.reflect.Field)
  166. */
  167. @SuppressWarnings("unchecked")
  168. public void update(LocalType bean, Connection connection, RelationQuery relationQuery) throws SQLException{
  169. if(!initialized){
  170. this.init();
  171. }
  172. try {
  173. RemoteType remoteBean = (RemoteType) field.get(bean);
  174. if(remoteBean != null){
  175. this.annotatedDAO.addOrUpdate(remoteBean, connection, relationQuery);
  176. }
  177. } catch (IllegalArgumentException e) {
  178. throw new RuntimeException(e);
  179. } catch (IllegalAccessException e) {
  180. throw new RuntimeException(e);
  181. }
  182. }
  183. private void init() {
  184. this.annotatedDAO = this.daoFactory.getDAO(remoteClass);
  185. this.queryParameterFactory = annotatedDAO.getParamFactory(remoteKeyField, remoteRemoteKeyClass);
  186. this.initialized = true;
  187. }
  188. /* (non-Javadoc)
  189. * @see se.unlogic.utils.dao.ManyToOneRelation#getField()
  190. */
  191. public Field getField() {
  192. return field;
  193. }
  194. /* (non-Javadoc)
  195. * @see se.unlogic.utils.dao.ManyToOneRelation#getBeanField()
  196. */
  197. public Field getBeanField() {
  198. return this.field;
  199. }
  200. /* (non-Javadoc)
  201. * @see se.unlogic.utils.dao.ManyToOneRelation#getParamType()
  202. */
  203. public Class<RemoteType> getParamType() {
  204. return remoteClass;
  205. }
  206. /* (non-Javadoc)
  207. * @see se.unlogic.utils.dao.ManyToOneRelation#isAutoGenerated()
  208. */
  209. public boolean isAutoGenerated() {
  210. return false;
  211. }
  212. public static <LT,RT,RKT> DefaultManyToOneRelation<LT, RT, RKT> getGenericInstance(Class<LT> beanClass, Class<RT> remoteClass, Class<RKT> remoteKeyClass, Field field, Field remoteField, DAOManaged daoManaged, AnnotatedDAOFactory daoFactory){
  213. return new DefaultManyToOneRelation<LT, RT, RKT>(beanClass, remoteClass, remoteKeyClass, field, remoteField, daoManaged, daoFactory);
  214. }
  215. }