Package se.unlogic.standardutils.dao

Source Code of se.unlogic.standardutils.dao.DefaultManyToOneRelation

/*******************************************************************************
* Copyright (c) 2010 Robert "Unlogic" Olofsson (unlogic@unlogic.se).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0-standalone.html
******************************************************************************/
package se.unlogic.standardutils.dao;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import se.unlogic.standardutils.annotations.UnsupportedFieldTypeException;
import se.unlogic.standardutils.dao.annotations.DAOManaged;
import se.unlogic.standardutils.dao.annotations.ManyToOne;
import se.unlogic.standardutils.populators.QueryParameterPopulator;
import se.unlogic.standardutils.populators.BeanStringPopulator;
import se.unlogic.standardutils.populators.BeanStringPopulatorRegistery;
import se.unlogic.standardutils.reflection.ReflectionUtils;
import se.unlogic.standardutils.string.StringUtils;

public class DefaultManyToOneRelation<LocalType,RemoteType, RemoteKeyType> implements ManyToOneRelation<LocalType, RemoteType, RemoteKeyType>{

  private final String columnName;
  private final Field field;
  private QueryParameterPopulator<RemoteKeyType> queryParameterPopulator;
  private Method queryMethod;
  private final BeanResultSetPopulator<RemoteKeyType> remoteKeyPopulator;
  private final Field remoteKeyField;

  private final AnnotatedDAOFactory daoFactory;
  private AnnotatedDAO<RemoteType> annotatedDAO;
  private QueryParameterFactory<RemoteType,RemoteKeyType> queryParameterFactory;
  private final Class<RemoteType> remoteClass;
  private final Class<RemoteKeyType> remoteRemoteKeyClass;

  private boolean initialized;

  public DefaultManyToOneRelation(Class<LocalType> beanClass, Class<RemoteType> remoteClass, Class<RemoteKeyType> remoteKeyClass, Field field, Field remoteKeyField, DAOManaged daoManaged, AnnotatedDAOFactory daoFactory) {

    this.remoteClass = remoteClass;
    this.remoteRemoteKeyClass = remoteKeyClass;
    this.field = field;
    this.remoteKeyField = remoteKeyField;
    this.daoFactory = daoFactory;

    if(!StringUtils.isEmpty(daoManaged.columnName())){
      this.columnName = daoManaged.columnName();
    }else{
      this.columnName = field.getName();
    }

    ReflectionUtils.fixFieldAccess(remoteKeyField);

    //TODO use column instead! somehow...
    Method resultSetMethod = ResultSetMethods.getColumnNameMethod(remoteKeyClass);

    if(resultSetMethod != null){
     
      remoteKeyPopulator = new MethodBasedResultSetPopulator<RemoteKeyType>(resultSetMethod, columnName);
     
    }else{
     
      BeanStringPopulator<RemoteKeyType> typePopulator = BeanStringPopulatorRegistery.getBeanStringPopulator(remoteKeyClass);
     
      if(typePopulator != null){
       
        remoteKeyPopulator = new TypeBasedResultSetPopulator<RemoteKeyType>(typePopulator, columnName);
      }else{

        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);
      }
    }
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getColumnName()
   */
  public String getColumnName(){

    return columnName;
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getQueryParameterPopulator()
   */
  public QueryParameterPopulator<RemoteKeyType> getQueryParameterPopulator(){

    if(queryParameterPopulator == null && queryMethod == null){

      if(!initialized){

        this.init();
      }

      this.queryParameterPopulator = annotatedDAO.getQueryParameterPopulator(remoteRemoteKeyClass);
    }

    return queryParameterPopulator;
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getQueryMethod()
   */
  public Method getQueryMethod(){

    if(this.queryMethod == null){
      this.queryMethod = PreparedStatementQueryMethods.getObjectQueryMethod();
    }

    return queryMethod;
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getBeanValue(LocalType)
   */
  @SuppressWarnings("unchecked")
  public RemoteKeyType getBeanValue(LocalType bean){

    try {
      RemoteType subBean = (RemoteType) field.get(bean);

      if(subBean == null){
        return null;
      }

      return (RemoteKeyType)remoteKeyField.get(subBean);

    } catch (IllegalArgumentException e) {

      throw new RuntimeException(e);

    } catch (IllegalAccessException e) {

      throw new RuntimeException(e);
    }
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getParamValue(java.lang.Object)
   */
  @SuppressWarnings("unchecked")
  public RemoteKeyType getParamValue(Object bean) {

    try {
      if(bean == null){
        return null;
      }

      return (RemoteKeyType) remoteKeyField.get(bean);

    } catch (IllegalArgumentException e) {

      throw new RuntimeException(e);

    } catch (IllegalAccessException e) {

      throw new RuntimeException(e);
    }
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#setValue(LocalType, java.sql.ResultSet, java.sql.Connection, java.lang.reflect.Field[])
   */
  public void getRemoteValue(LocalType bean, ResultSet resultSet, Connection connection, RelationQuery relationQuery) throws SQLException{

    try {

      if(!initialized){
        this.init();
      }

      RemoteKeyType keyValue = remoteKeyPopulator.populate(resultSet);

      if(keyValue != null){

        HighLevelQuery<RemoteType> query = new HighLevelQuery<RemoteType>();

        query.addParameter(queryParameterFactory.getParameter(keyValue));
       
        if(relationQuery != null){
          query.disableAutoRelations(relationQuery.isDisableAutoRelations());
        }
       
        query.addRelations(relationQuery);

        RemoteType remoteBeanInstance = annotatedDAO.get(query ,connection);

        this.getField().set(bean, remoteBeanInstance);
      }

    } catch (IllegalArgumentException e) {

      throw new RuntimeException(e);

    } catch (IllegalAccessException e) {

      throw new RuntimeException(e);
    }
  }



  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#add(LocalType, java.sql.Connection, java.lang.reflect.Field)
   */
  @SuppressWarnings("unchecked")
  public void add(LocalType bean, Connection connection, RelationQuery relationQuery) throws SQLException{

    if(!initialized){
      this.init();
    }

    try {
      RemoteType remoteBean = (RemoteType) field.get(bean);

      if(remoteBean != null){

        this.annotatedDAO.add(remoteBean, connection, relationQuery);
      }

    } catch (IllegalArgumentException e) {

      throw new RuntimeException(e);

    } catch (IllegalAccessException e) {

      throw new RuntimeException(e);
    }

  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#update(LocalType, java.sql.Connection, java.lang.reflect.Field)
   */
  @SuppressWarnings("unchecked")
  public void update(LocalType bean, Connection connection, RelationQuery relationQuery) throws SQLException{

    if(!initialized){
      this.init();
    }

    try {
      RemoteType remoteBean = (RemoteType) field.get(bean);

      if(remoteBean != null){

        this.annotatedDAO.addOrUpdate(remoteBean, connection, relationQuery);
      }

    } catch (IllegalArgumentException e) {

      throw new RuntimeException(e);

    } catch (IllegalAccessException e) {

      throw new RuntimeException(e);
    }

  }

  private void init() {

    this.annotatedDAO = this.daoFactory.getDAO(remoteClass);
    this.queryParameterFactory = annotatedDAO.getParamFactory(remoteKeyField, remoteRemoteKeyClass);

    this.initialized = true;
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getField()
   */
  public Field getField() {

    return field;
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getBeanField()
   */
  public Field getBeanField() {

    return this.field;
  }

  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#getParamType()
   */
  public Class<RemoteType> getParamType() {

    return remoteClass;
  }


  /* (non-Javadoc)
   * @see se.unlogic.utils.dao.ManyToOneRelation#isAutoGenerated()
   */
  public boolean isAutoGenerated() {

    return false;
  }

  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){

    return new DefaultManyToOneRelation<LT, RT, RKT>(beanClass, remoteClass, remoteKeyClass, field, remoteField, daoManaged, daoFactory);
  }
}
TOP

Related Classes of se.unlogic.standardutils.dao.DefaultManyToOneRelation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.