JdbcTypeMap.java :  » Database-ORM » ebean » com » avaje » util » codegen » Java Open Source

Java Open Source » Database ORM » ebean 
ebean » com » avaje » util » codegen » JdbcTypeMap.java
/**
 * Copyright (C) 2006  Robin Bygrave
 * 
 * This file is part of Ebean.
 * 
 * Ebean is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *  
 * Ebean is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Ebean; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA  
 */
package com.avaje.util.codegen;

import java.math.BigInteger;
import java.sql.Types;
import java.util.HashMap;

import javax.persistence.PersistenceException;

import com.avaje.ebean.server.plugin.PluginProperties;
import com.avaje.ebean.util.DataTypes;
import com.avaje.ebean.util.Message;

/**
 * Maps Class types to JDBC datatypes.
 */
public class JdbcTypeMap {

  private static final int[] charTypes = { Types.CHAR, Types.VARCHAR, Types.LONGVARCHAR, Types.CLOB };

  private final HashMap classToSqltype = new HashMap();

  private final HashMap classToSqltypeLogical = new HashMap();

  private final HashMap sqltypeToClass = new HashMap();

  /**
   * The default type to map a java.util.Date to.
   */
  private final int defaultUtilDateType;
  
  /**
   * The default type to map a java.util.Calender to.
   */
  private final int defaultUtilCalenderType;
  
  /**
   * The default type to map a Enum to.
   */
  private final int defaultEnumType;
  
  /**
   * Create the default mapping.
   */
  public JdbcTypeMap() {
    this(null);
  }
  
  /**
   * Create the mapping for a given ServerPlugin.
   */
  public JdbcTypeMap(PluginProperties properties) {

    // load standard JDBC types mapping from Classes
    JdbcTypeMapFactory.addTypes(classToSqltype);
    
    //TODO: Control mapping of BigInteger to something other than Long?
    // BigInteger support built in - mapping to a Long, Hmm.
    classToSqltype.put(BigInteger.class, Types.BIGINT);
    
    // add logical types (java.util.Date etc)
    JdbcTypeMapFactory.addTypesLogical(classToSqltypeLogical);

    // reverse of JDBC types mapping 
    JdbcTypeMapFactory.addReverse(sqltypeToClass);

    
    if (properties != null){
      String enumType = properties.getProperty("type.mapping.enum", "string");
      defaultEnumType = getEnumMapType(enumType);
      
      // by default map anonymous java.util.Date to java.sql.Timestamp.
      String mapType = properties.getProperty("type.mapping.java.util.Date", null);
      defaultUtilDateType = getTemporalMapType(mapType);
    
      // by default map anonymous java.util.Calendar to java.sql.Timestamp.
      mapType = properties.getProperty("type.mapping.java.util.Calendar",  null);
      defaultUtilCalenderType = getTemporalMapType(mapType);
    } else {
      defaultEnumType = Types.VARCHAR;
      // leaving these 0 means the @Temporal annotation is required
      // if they are non 0 then @Temporal is not required (uses default)
      defaultUtilDateType = 0;
      defaultUtilCalenderType = 0;
    }
    
    if (defaultUtilDateType != 0){
      // default mapping of java.util.Date
      classToSqltype.put(java.util.Date.class, defaultUtilDateType);
    }
    if (defaultUtilCalenderType != 0){
      // default mapping of java.util.Calendar
      classToSqltype.put(java.util.Calendar.class, defaultUtilCalenderType);
    }
  }

  /**
   * Determine the default type to convert Enum's to.
   */
  private int getEnumMapType(String mapType) {
    if (mapType == null){
      return 0;
    }
    if (mapType.equalsIgnoreCase("string")) {
      return java.sql.Types.VARCHAR;
    }
    if (mapType.equalsIgnoreCase("integer")) {
      return java.sql.Types.INTEGER;
    }
    if (mapType.equalsIgnoreCase("ordinal")) {
      return java.sql.Types.INTEGER;
    }
    String m = "Expected string or ordinal but got ["+mapType+"]";
    throw new IllegalArgumentException(m);
  }
  
  /**
   * Convert the mapType String to java.sql.Types DATE TIME or TIMESTAMP.
   */
  private int getTemporalMapType(String mapType) {
    if (mapType == null){
      return 0;
    }
    if (mapType.equalsIgnoreCase("time")) {
      return java.sql.Types.TIME;
    }
    if (mapType.equalsIgnoreCase("date")) {
      return java.sql.Types.DATE;
    }
    return java.sql.Types.TIMESTAMP;
  }
  
  /**
   * Return the Class mapped to the jdbc type.
   * <p>
   * Used to determine the propertyType for MapBeans.
   * </p>
   */
  public Class getReverse(int jdbcType) {
    return (Class) sqltypeToClass.get(Integer.valueOf(jdbcType));
  }

  /**
   * Return the jdbc type for a given java class.
   */
  public int getDbType(Class clz) {
    if (clz.isEnum()){
      // this is the default type to convert an Enum to but
      // could be overridden by deployment annotation
      return defaultEnumType;
    }
    Integer type = (Integer) classToSqltype.get(clz);
    if (type != null) {
      return type.intValue();
    }
    throw new PersistenceException(Message.msg("jdbc.type.notmapped", clz.getName()));
  }

  /**
   * Returns a Type often matching getDbType() but with the addition of
   * java.util.Date, java.util.Calendar and java.math.BigInteger.
   * <p>
   * A BeanProperty can have both a dbType and logicalType and most of the
   * time they will be equal. When they are not equal then some type
   * conversion is required.
   * </p>
   */
  public int getLogicalType(Class clz) {
    // Check for Enum first. As subclasses are not in
    // the classToSqltypeLogical map.
    if (clz.isEnum()){
      return DataTypes.ENUM;
    }
    
    // search for 'logical only' types (such as java.util.Date)
    Integer type = (Integer) classToSqltypeLogical.get(clz);
    if (type == null) {
      // often just the same as DB type 
      type = (Integer) classToSqltype.get(clz);
    }
    if (type != null) {
      return type.intValue();
    }
    throw new PersistenceException(Message.msg("jdbc.type.notmapped", clz.getName()));
  }

  /**
   * Return true if the type is one of CHAR, VARCHAR, CLOB or LONGVARCHAR.
   */
  public boolean isCharacterType(int type) {
    for (int i = 0; i < charTypes.length; i++) {
      if (charTypes[i] == type) {
        return true;
      }
    }
    return false;
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.