Package siena.jdbc

Source Code of siena.jdbc.JdbcMappingUtils

package siena.jdbc;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import siena.ClassInfo;
import siena.Json;
import siena.Query;
import siena.QueryJoin;
import siena.SienaException;
import siena.Util;
import siena.core.DecimalPrecision;
import siena.core.Polymorphic;
import siena.embed.Embedded;
import siena.embed.JsonSerializer;
import siena.jdbc.JdbcPersistenceManager.JdbcClassInfo;

public class JdbcMappingUtils {
  public static <T> List<Field> getJoinFields(Query<T> query) {
    List<Field> joinFields = null;
    // adds all join fields brought by call to .join() functions
    if(query.getJoins().size()>0){
      joinFields = new ArrayList<Field>();
      for(QueryJoin join:query.getJoins())
        joinFields.add(join.field);
    }
    // then adds the remaining joins coming from @Join if not added yet
    ClassInfo ci = ClassInfo.getClassInfo(query.getQueriedClass());
    if(ci.joinFields.size() > 0){
      if(joinFields == null) joinFields = new ArrayList<Field>();
      for(Field f: ci.joinFields){
        if(!joinFields.contains(f)) joinFields.add(f);
      }
    }
    return joinFields;
  }
 
  public static <T> List<Field> getJoinFields(Query<T> query, JdbcClassInfo info) {
    List<Field> joinFields = null;
    // adds all join fields brought by call to .join() functions
    if(query.getJoins()!=null && query.getJoins().size()>0){
      joinFields = new ArrayList<Field>();
      for(QueryJoin join:query.getJoins())
        joinFields.add(join.field);
    }
    // then adds the remaining joins coming from @Join if not added yet
    if(info.joinFields!=null && info.joinFields.size() > 0){
      if(joinFields == null) joinFields = new ArrayList<Field>();
      for(Field f: info.joinFields){
        if(!joinFields.contains(f)) joinFields.add(f);
      }
    }
    return joinFields;
  }
 
  public static <T> T mapObject(Class<T> clazz, ResultSet rs, String tableName, List<Field >joinFields) {
    try {
      T obj = Util.createObjectInstance(clazz);
      mapObject(obj, rs, tableName, joinFields);
      return obj;
    } catch(SienaException e) {
      throw e;
    } catch(Exception e) {
      throw new SienaException(e);
    }
  }

  public static void mapObject(Object obj, ResultSet rs, String tableName, List<Field >joinFields) {
    Class<?> clazz = obj.getClass();
    for (Field field : JdbcClassInfo.getClassInfo(clazz).allFields) {
      mapField(obj, field, rs, tableName, joinFields);
    }
  }

  public static <T> List<T> mapList(Class<T> clazz, ResultSet rs, String tableName, List<Field> joinFields, int pageSize) {
    try {
      List<T> objects = new ArrayList<T>();
      if(pageSize==0){
        while(rs.next()) {
          objects.add(mapObject(clazz, rs, tableName, joinFields));
        }
      }else {
        for(int i=0; i<pageSize && rs.next();i++){
          objects.add(mapObject(clazz, rs, tableName, joinFields));
        }
      }
      return objects;
    } catch(SienaException e) {
      throw e;
    } catch(Exception e) {
      throw new SienaException(e);
    }
  }
 
 
  public static <T> T mapObjectKeys(Class<T> clazz, ResultSet rs, String tableName, List<Field> joinFields) {
    try {
      T obj = Util.createObjectInstance(clazz);
      mapObjectKeys(obj, rs, tableName, joinFields);
      return obj;
    } catch(SienaException e) {
      throw e;
    } catch(Exception e) {
      throw new SienaException(e);
    }
  }

  public static void mapObjectKeys(Object obj, ResultSet rs, String tableName, List<Field> joinFields) {
    Class<?> clazz = obj.getClass();
    for (Field field : JdbcClassInfo.getClassInfo(clazz).keys) {
      mapField(obj, field, rs, tableName, joinFields);
    }
  }
 
  public static <T> List<T> mapListKeys(Class<T> clazz, ResultSet rs, String tableName, List<Field> joinFields, int pageSize) {
    try {
      List<T> objects = new ArrayList<T>();
      if(pageSize==0){
        while(rs.next()) {
        objects.add(mapObjectKeys(clazz, rs, tableName, joinFields));
        }
      }else {
        for(int i=0; i<pageSize && rs.next();i++){
          objects.add(mapObjectKeys(clazz, rs, tableName, joinFields));
        }
      }
      return objects;
    } catch(SienaException e) {
      throw e;
    } catch(Exception e) {
      throw new SienaException(e);
    }
  }

  public static void mapField(Object obj, Field field, ResultSet rs, String tableName, List<Field> joinFields) {
    Class<?> type = field.getType();
    //field.setAccessible(true);
    try {
      if(ClassInfo.isModel(type) && !ClassInfo.isEmbedded(field)) {
        JdbcClassInfo fieldClassInfo = JdbcClassInfo.getClassInfo(type);
       
        if(joinFields==null || joinFields.size()==0 || !joinFields.contains(field)){
          String[] fks = ClassInfo.getColumnNames(field, tableName);
          Object rel = Util.createObjectInstance(type);
          boolean none = false;
          int i = 0;
          checkForeignKeyMapping(fieldClassInfo.keys, fks, obj.getClass(), field);
          for(Field f : fieldClassInfo.keys) {
            Object o = rs.getObject(JdbcClassInfo.aliasFromCol(fks[i++]));
            if(o == null) {
              none = true;
              break;
            }
            setFromObject(rel, f, o);
          }
          if(!none){
            Util.setField(obj, field, rel);
            //field.set(obj, rel);
          }
        }
        else {
          // this is a JOIN field
          // first verifies the field is not null
          Object val = rs.getObject(
              JdbcClassInfo.aliasFromCol(
                  ClassInfo.getColumnNames(field, tableName)[0]));
          if(val == null){
            Util.setField(obj, field, null);
            return;
          }
          // uses join field alias
          // Object rel = mapObject(type, rs, fieldClassInfo.tableName, null);
          Object rel = mapObject(type, rs, fieldClassInfo.joinFieldAliases.get(field.getName()), null);
          Util.setField(obj, field, rel);
        }
      } else {
        Object val = rs.getObject(ClassInfo.getColumnNames(field, tableName)[0].replace('.', '_'));
        setFromObject(obj, field, val);
      }
    } catch (SienaException e) {
      throw e;
    } catch (Exception e) {
      throw new SienaException(e);
    }
  }
 
  public static void checkForeignKeyMapping(List<Field> keys, String[] columns, Class<?> clazz, Field field) {
    if (keys.size() != columns.length) {
      throw new SienaException("Bad mapping for field '"+field.getName()+"'. " +
          "Related class "+field.getType().getName()+" has "+keys.size()+" primary keys, " +
          "but '"+clazz.getName()+"' only has mappings for "+columns.length+" foreign keys");
    }
  }
 
  public static void setFromObject(Object object, Field f, Object value)
    throws IllegalArgumentException, IllegalAccessException {
    Util.setField(object, f, fromObject(f, value));
  }
 
  public static Object fromObject(Field field, Object value) {
    Class<?> type = field.getType();
    // in H2 database, mediumtext is mapped to CLOB
    if(Json.class.isAssignableFrom(type) && value != null && java.sql.Clob.class.isAssignableFrom(value.getClass())) {
      java.sql.Clob clob = (java.sql.Clob)value;
      try {
        return Json.load(new BufferedReader(clob.getCharacterStream()));
      } catch (SQLException e) {
        throw new SienaException(e);
      }
    }

    if(field.getAnnotation(Embedded.class) != null && value != null && java.sql.Clob.class.isAssignableFrom(value.getClass())) {
      java.sql.Clob clob = (java.sql.Clob)value;
      try {
        Json data = Json.load(new BufferedReader(clob.getCharacterStream()));
        return JsonSerializer.deserialize(field, data);
      } catch (SQLException e) {
        throw new SienaException(e);
      }
    }

        // issue https://github.com/mandubian/siena/issues/5
        if (value != null && java.sql.Clob.class.isAssignableFrom(value.getClass())) {
            java.sql.Clob clob = (java.sql.Clob) value;
            try {
                // @see http://osdir.com/ml/h2-database/2011-06/msg00170.html
                return clob.getSubString(1, (int) clob.length());
            } catch (SQLException e) {
                throw new SienaException(e);
            }
        }

   
    if(field.isAnnotationPresent(Polymorphic.class)){
      try {
        if(java.sql.Blob.class.isAssignableFrom(value.getClass())){
          java.sql.Blob blob = (java.sql.Blob)value;
          ObjectInputStream in =
            new ObjectInputStream(new ByteArrayInputStream(blob.getBytes(0, (int)blob.length())));
          return in.readObject();
        }else {
          ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream((byte[])value));
          return in.readObject();
        }
      } catch (IOException e) {
        throw new SienaException(e);
      } catch (ClassNotFoundException e) {
        throw new SienaException(e);
      } catch(SQLException e){
        throw new SienaException(e);
      }
    }
   
    if(byte[].class == type && value != null && java.sql.Blob.class.isAssignableFrom(value.getClass())){
      java.sql.Blob blob = (java.sql.Blob)value;
      try {
        // converts the blob into a byte[]...
        // TODO what to do with a very long blob????
        return blob.getBytes(0, (int)blob.length());
      } catch (SQLException e) {
        throw new SienaException(e);
      }
    }
    if(BigDecimal.class == type){
      DecimalPrecision ann = field.getAnnotation(DecimalPrecision.class);
      if(ann==null){
        return (BigDecimal)value;
      }else {
        switch(ann.storageType()){
        case DOUBLE:
          return BigDecimal.valueOf((Double)value);
        case STRING:
          return new BigDecimal((String)value);
        case NATIVE:
          return (BigDecimal)value;
        }
      }
    }
    return Util.fromObject(field, value);
  }
}
TOP

Related Classes of siena.jdbc.JdbcMappingUtils

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.