/**
   * {@link ValueType}を処理します。
   *
   * @param propertyMeta プロパティメタデータ
   * @param entityMeta エンティティメタデータ
   */
  @SuppressWarnings("unchecked")
  protected void doValueType(final PropertyMeta propertyMeta, final EntityMeta entityMeta) {
    final Class<?> propertyClass = propertyMeta.getPropertyClass();
    final ValueType valueType = valueTypes.get(propertyClass);
    if (valueType != null) {
      propertyMeta.setValueType(valueType);
      return;
    }

    if (propertyClass == String.class) {
      if (propertyMeta.isLob()) {
        propertyMeta.setValueType(ValueTypes.CLOB);
      } else {
        propertyMeta.setValueType(ValueTypes.STRING);
      }
      return;
    }

    if (propertyClass == byte[].class) {
      if (propertyMeta.isLob()) {
        propertyMeta.setValueType(ValueTypes.BLOB);
      } else {
        propertyMeta.setValueType(ValueTypes.BYTE_ARRAY);
      }
      return;
    }

    if (propertyClass == Date.class) {
      switch (propertyMeta.getTemporalType()) {
        case DATE:
          propertyMeta.setValueType(ValueTypes.DATE_SQLDATE);
          return;
        case TIME:
          propertyMeta.setValueType(ValueTypes.DATE_TIME);
          return;
        case TIMESTAMP:
          propertyMeta.setValueType(ValueTypes.DATE_TIMESTAMP);
          return;
      }
    }

    if (propertyClass == Calendar.class) {
      switch (propertyMeta.getTemporalType()) {
        case DATE:
          propertyMeta.setValueType(ValueTypes.CALENDAR_SQLDATE);
          return;
        case TIME:
          propertyMeta.setValueType(ValueTypes.CALENDAR_TIME);
          return;
        case TIMESTAMP:
          propertyMeta.setValueType(ValueTypes.CALENDAR_TIMESTAMP);
          return;
      }
    }

    if (propertyClass.isEnum()) {
      if (propertyMeta.getEnumType() == null) {
        propertyMeta.setValueType(ValueTypes.getValueType(propertyClass));
        return;
      }
      switch (propertyMeta.getEnumType()) {
        case ORDINAL:
          propertyMeta.setValueType(ValueTypes.getEnumOrdinalValueType(propertyClass));
          return;
        case STRING:
          propertyMeta.setValueType(ValueTypes.getEnumStringValueType(propertyClass));
          return;
      }
    }

    final ValueType userDefinedValueType = ValueTypes.createUserDefineValueType(propertyClass);
    if (userDefinedValueType != null) {
      propertyMeta.setValueType(userDefinedValueType);
      return;
    }

    if (Serializable.class.isAssignableFrom(propertyClass)) {
      if (propertyMeta.isLob()) {
        propertyMeta.setValueType(ValueTypes.SERIALIZABLE_BLOB);
      } else {
        propertyMeta.setValueType(ValueTypes.SERIALIZABLE_BYTE_ARRAY);
      }
      return;
    }

    throw new UnsupportedPropertyTypeRuntimeException(
        entityMeta.getName(), propertyMeta.getName(), propertyMeta.getPropertyClass());
  }