Package com.cosmo.orm

Source Code of com.cosmo.orm.OrmFactory

package com.cosmo.orm;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import com.cosmo.Workspace;
import com.cosmo.data.DataAgent;
import com.cosmo.data.DataException;
import com.cosmo.data.DataFactory;
import com.cosmo.net.HttpRequestUtils;
import com.cosmo.orm.annotations.CormFieldSetter;
import com.cosmo.orm.annotations.CormObject;
import com.cosmo.orm.annotations.CormObjectField;
import com.cosmo.orm.annotations.CormObjectField.FieldSortType;

/**
* Implementa un acceso uniforme a los drivers CORM.<br />
* Esta clase se encarga de instanciar el driver adecuado (seg�n la configuraci�n) y de manejar las llamadas a m�todos.
*
* @author Gerard Llort
*/
public class OrmFactory
{
   // Declaraci�n de variables locales
   OrmDriver driver;


   //==============================================
   // Constructors
   //==============================================

   /**
    * Constructor de la clase {@link OrmFactory}.
    *
    * @param dataSourceId Una cadena que contiene el identificador del DataSource definido en la configuraci�n.
    * @param workspace Una instancia de {@link Workspace} que representa el contexto actual de la aplicaci�n.
    */
   public OrmFactory(String dataSourceId, Workspace workspace) throws OrmDriverException
   {
      this.driver = loadDriver(dataSourceId, workspace);
   }


   //==============================================
   // Properties
   //==============================================

   /**
    * Devuelve el nombre del proveedor.<br />
    * Debe especificar claramente para qu� gestor de BBDD est� implementado (nombre del producto).
    */
   public String getProviderName()
   {
      return driver.getProviderName();
   }

   /**
    * Devuelve el nombre cualificado de la clase que act�a de driver para la conexi�n JDBC.
    */
   public String getJdbcDriver()
   {
      return driver.getJdbcDriver();
   }

   /**
    * Obtiene el resultado de una consulta.
    *
    * @param ormObject Una referencia a un objeto CORM (clase POJO que est� anotada con anotaciones CORM).
    *
    * @return Una instancia de {@link ResultSet} que contiene los datos obtenidos en la consulta.
    *
    * @throws InvalidMappingException
    * @throws SQLException
    * @throws DataException
    * @throws Exception
    */
   public ResultSet select(Class<?> ormObject) throws InvalidMappingException, SQLException, DataException, Exception
   {
      return driver.select(ormObject);
   }

   /**
    * Obtiene el resultado de una consulta.
    *
    * @param ormObject Una referencia a un objeto CORM (clase POJO que est� anotada con anotaciones CORM).
    *
    * @return Una instancia de {@link ResultSet} que contiene los datos obtenidos en la consulta.
    *
    * @throws InvalidMappingException
    * @throws SQLException
    * @throws DataException
    * @throws Exception
    */
   public ResultSet select(Class<?> ormObject, boolean showAllColumns) throws InvalidMappingException, SQLException, DataException, Exception
   {
      return driver.select(ormObject, showAllColumns);
   }

   /**
    * Genera una sent�ncia SELECT a partir de una instancia de un objeto CORM.
    *
    * @param ormObject Una referencia a un objeto CORM (clase POJO que est� anotada con anotaciones CORM).
    *
    * @return Una instancia de {@link ResultSet} que contiene los datos obtenidos en la consulta.
    *
    * @throws InvalidMappingException
    * @throws ClassNotFoundException
    * @throws DataException
    * @throws SQLException
    * @throws Exception
    */
   public Object get(Object data) throws InvalidMappingException, SQLException, DataException, Exception
   {
      return driver.get(data);
   }

   /**
    * Genera una sent�ncia INSERT INTO a partir de una instancian de clase.
    *
    * @param data Clase que contiene los datos a insertar.
    *
    * @throws InvalidMappingException
    * @throws DataException
    * @throws SQLException
    * @throws Exception
    */
   public void insert(Object data) throws InvalidMappingException, SQLException, DataException, Exception
   {
      driver.insert(data);
   }

   /**
    * Actualiza la informaci�n del registro de la tabla de datos que indica el valor asociado a/los campo/s identificador/es.
    *
    * @param ormClass Una referencia a un objeto CORM (clase POJO que est� anotada con anotaciones CORM).
    * @param request Una instancia de {@link HttpServletRequest} que contiene los datos (par�metros) usados para ejecutar la sent�ncia UPDATE.
    *
    * @throws Exception
    * @throws DataException
    * @throws SQLException
    * @throws InvalidMappingException
    */
   public void update(Object data) throws InvalidMappingException, SQLException, DataException, Exception
   {
      driver.update(data);
   }

   /**
    * Elimina el registro de la tabla de datos que indica el valor asociado a/los campo/s identificador/es.
    *
    * @param data Una instancia de un objeto CORM que contiene los datos para el borrado (todos los campos de la clave principal establecidos).
    *
    * @throws Exception
    * @throws DataException
    * @throws SQLException
    * @throws InvalidMappingException
    */
   public void delete(Object data) throws InvalidMappingException, SQLException, DataException, Exception
   {
      driver.delete(data);
   }


   //==============================================
   // Static members
   //==============================================

   /**
    * Recupera una instancia desde la URL.
    *
    * @param ormClass Una referencia a un objeto CORM (clase POJO que est� anotada con anotaciones CORM).
    * @param request Una instancia de {@link HttpServletRequest} que contiene los datos de la instancia.
    *
    * @return
    *
    * @throws InvalidMappingException
    * @throws OrmException
    * @throws InvocationTargetException
    * @throws IllegalAccessException
    * @throws InstantiationException
    * @throws IllegalArgumentException
    */
   public static Object getObjectFromRequest(Class<?> ormClass, HttpServletRequest request) throws InvalidMappingException, OrmException
   {
      Object instance = null;
      CormFieldSetter cfs;
      Class<?> paramType;

      // Comprueba si el objeto proporcionado es un objeto CORM v�lido
      if (!OrmFactory.isValidCormObject(ormClass))
      {
         throw new InvalidMappingException(ormClass.getName() + " is not a CORM object.");
      }

      // Genera la instancia de la clase
      try
      {
         Constructor<?>[] ctors = ormClass.getDeclaredConstructors();
         for (Constructor<?> ctor : ctors)
         {
            if (ctor.getGenericParameterTypes().length == 0)
            {
               ctor.setAccessible(true);
               instance = ctor.newInstance();
            }
         }
      }
      catch (Exception ex)
      {
         throw new OrmException(ex.getMessage(), ex);
      }

      // Establece los valores de las propiedades con el contenido de los par�metros contenidos en el Request
      try
      {
         for (Method method : ormClass.getMethods())
         {
            if (method.isAnnotationPresent(CormFieldSetter.class))
            {
               method.setAccessible(true);
               cfs = method.getAnnotation(CormFieldSetter.class);
               paramType = method.getParameterTypes()[0];

               // Establece el valor seg�n el tipo de datos
               if ((paramType == String.class) || (paramType == char.class))
               {
                  method.invoke(instance, HttpRequestUtils.getValue(request, cfs.dbTableColumn(), ""));
               }
               else if ((paramType == Integer.class) || (paramType == int.class) ||
                        (paramType == Long.class) || (paramType == long.class) ||
                        (paramType == Short.class) || (paramType == short.class) ||
                        (paramType == Byte.class) || (paramType == byte.class))
               {
                  method.invoke(instance, HttpRequestUtils.getInt(request, cfs.dbTableColumn()));
               }
               else if ((paramType == Float.class) || (paramType == float.class) ||
                        (paramType == Double.class) || (paramType == double.class))
               {
                  method.invoke(instance, HttpRequestUtils.getDouble(request, cfs.dbTableColumn()));
               }
               else if ((paramType == Boolean.class) || (paramType == boolean.class))
               {
                  method.invoke(instance, HttpRequestUtils.getBoolean(request, cfs.dbTableColumn()));
               }
               else if (paramType == Date.class)
               {
                  method.invoke(instance, HttpRequestUtils.getDate(request, cfs.dbTableColumn()));
               }
            }
         }
      }
      catch (Exception ex)
      {
         throw new OrmException(ex.getMessage(), ex);
      }

      return instance;
   }

   /**
    * Determina si una clase es un objeto CORM (Cosmo ORM).
    * <br /><br />
    * B�sicamente comprueba que disponga de la anotaci�n {@link CormObject} y que al menos tenga una anotaci�n {@link CormObjectField}
    * (es decir, que tenga al menos un atributo).
    *
    * @param ormClass Clase a comprobar.
    *
    * @return Devuelve {@code true} si la clase est� definida como objeto CORM o {@code false} en cualquier otro caso.
    */
   public static boolean isValidCormObject(Class<?> ormClass)
   {
      if (!ormClass.isAnnotationPresent(CormObject.class))
      {
         return false;
      }

      boolean isValid = false;
      for (Method method : ormClass.getMethods())
      {
         isValid = isValid || method.isAnnotationPresent(CormObjectField.class);
      }

      return isValid;
   }

   /**
    * Obtiene el nombre de la tabla de base de datos de un objeto CORM (Cosmo ORM).
    *
    * @param ormClass Clase a comprobar.
    *
    * @return Una cadena que contiene el nombre de la tabla o {@code null} en cualquier otro caso.
    *
    * @throws InvalidMappingException
    */
   public static String getDbTableName(Class<?> ormClass) throws InvalidMappingException
   {
      CormObject co = ormClass.getAnnotation(CormObject.class);
      if (co != null)
      {
         return co.dbTable();
      }

      throw new InvalidMappingException(ormClass.getName() + " is not a CORM object.");
   }

   /**
    * Determina si un objeto CORM (Cosmo ORM) tiene clave/s primaria/s definida/s.
    *
    * @param ormClass Clase a comprobar.
    *
    * @return Devuelve {@code true} si el objeto dispone de clave/s primaria/s o {@code false} en cualquier otro caso.
    */
   public static boolean havePrimaryKey(Class<?> ormClass)
   {
      if (!ormClass.isAnnotationPresent(CormObject.class))
      {
         return false;
      }

      boolean isValid = false;
      for (Method method : ormClass.getMethods())
      {
         if (method.isAnnotationPresent(CormObjectField.class))
         {
            isValid = isValid || method.getAnnotation(CormObjectField.class).isPrimaryKey();
         }
      }

      return isValid;
   }

   /**
    * Determina si una instancia de un objeto CORM dispone de campos ordenados.
    *
    * @param ormClass Clase a comprobar.
    *
    * @return Devuelve {@code true} si la clase dispone de propiedades ordenadas o {@code false} en cualquier otro caso.
    */
   public static boolean haveSortedFields(Class<?> ormClass)
   {
      CormObjectField cfg;

      for (Method method : ormClass.getMethods())
      {
         cfg = method.getAnnotation(CormObjectField.class);

         if (cfg != null)
         {
            if (cfg.sort() != FieldSortType.None)
            {
               return true;
            }
         }
      }

      return false;
   }


   //==============================================
   // Private members
   //==============================================

   /**
    * Carga el controlador de usuarios.
    *
    * @throws OrmDriverException
    */
   private static OrmDriver loadDriver(String dataSourceId, Workspace workspace) throws OrmDriverException
   {
      OrmDriver provider;
      DataAgent conn = null;

      try
      {
         // Genera la conexi�n
         conn = DataFactory.getInstance(workspace, dataSourceId);

         // Invoca el constructor del driver
         Class<?> cls = Class.forName(conn.getCompatibleOrmDriver());
         Constructor<?> cons = cls.getConstructor(DataAgent.class);
         provider = (OrmDriver) cons.newInstance(conn);

         return provider;
      }
      catch (NoSuchMethodException ex)
      {
         throw new OrmDriverException("CORM driver loader: NoSuchMethodException: " + (conn != null ? conn.getCompatibleOrmDriver() : "[unknown ORM driver]"), ex);
      }
      catch (InvocationTargetException ex)
      {
         throw new OrmDriverException("CORM driver loader: InvocationTargetException: " + (conn != null ? conn.getCompatibleOrmDriver() : "[unknown ORM driver]"), ex);
      }
      catch (ClassNotFoundException ex)
      {
         throw new OrmDriverException("CORM driver loader: ClassNotFoundException: " + (conn != null ? conn.getCompatibleOrmDriver() : "[unknown ORM driver]"), ex);
      }
      catch (InstantiationException ex)
      {
         throw new OrmDriverException("CORM driver loader: InstantiationException: " + (conn != null ? conn.getCompatibleOrmDriver() : "[unknown ORM driver]"), ex);
      }
      catch (IllegalAccessException ex)
      {
         throw new OrmDriverException("CORM driver loader: IllegalAccessException: " + (conn != null ? conn.getCompatibleOrmDriver() : "[unknown ORM driver]"), ex);
      }
      catch (DataException ex)
      {
         throw new OrmDriverException("CORM driver loader: " + (conn != null ? conn.getCompatibleOrmDriver() : "[unknown ORM driver]"), ex);
      }
   }
}
TOP

Related Classes of com.cosmo.orm.OrmFactory

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.