예제 #1
0
  /**
   * 查找自增主键并填充到队列中
   *
   * @param objs 填充对象
   * @throws IllegalArgumentException exception
   * @throws IllegalAccessException exception
   * @throws SQLException exception
   */
  public void find(Object... objs)
      throws IllegalArgumentException, IllegalAccessException, SQLException {
    Class<?> clz = objs[0].getClass();
    Field[] fields = clz.getDeclaredFields();
    for (Field field : fields) {
      ORMColumn oc = field.getAnnotation(ORMColumn.class);
      if (oc != null && oc.physicalPkFld() && oc.autoIncrement()) {
        // 找到最后一个自增id
        QueryRunner qr = new QueryRunner();
        Object identityVal = qr.query(conn, selectKey.getQuery(), new ScalarHandler<Object>());
        Long identity = NumberUtils.parseNumber(identityVal.toString(), Long.class);

        field.setAccessible(true);
        // 填充到所有当中
        for (int i = objs.length - 1; i >= 0; i--) {
          if (field.get(objs[i]) == null) { // 判null,要求主键都是包装类
            // 类型转换
            @SuppressWarnings("unchecked")
            Object val =
                NumberUtils.convertNumberToTargetClass(identity, ((Class<Number>) field.getType()));
            field.set(objs[i], val);
            identity--;
          }
        }
        break;
      }
    }
  }
예제 #2
0
 /** Coerce a Number value into the required target class, if necessary. */
 @Override
 public void setValue(Object value) {
   if (value instanceof Number) {
     super.setValue(NumberUtils.convertNumberToTargetClass((Number) value, this.numberClass));
   } else {
     super.setValue(value);
   }
 }
  /**
   * Convert the value to the required type (if necessary from a String), for the specified
   * property.
   *
   * @param propertyName name of the property
   * @param oldValue the previous value, if available (may be {@code null})
   * @param newValue the proposed new value
   * @param requiredType the type we must convert to (or {@code null} if not known, for example in
   *     case of a collection element)
   * @param typeDescriptor the descriptor for the target property or field
   * @return the new value, possibly the result of type conversion
   * @throws IllegalArgumentException if type conversion failed
   */
  @SuppressWarnings("unchecked")
  public <T> T convertIfNecessary(
      String propertyName,
      Object oldValue,
      Object newValue,
      Class<T> requiredType,
      TypeDescriptor typeDescriptor)
      throws IllegalArgumentException {

    // Custom editor for this type?
    PropertyEditor editor =
        this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);

    ConversionFailedException conversionAttemptEx = null;

    // No custom editor but custom ConversionService specified?
    ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
    if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
      TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
      if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
        try {
          return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
        } catch (ConversionFailedException ex) {
          // fallback to default conversion logic below
          conversionAttemptEx = ex;
        }
      }
    }

    Object convertedValue = newValue;

    // Value not of required type?
    if (editor != null
        || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
      if (typeDescriptor != null
          && requiredType != null
          && Collection.class.isAssignableFrom(requiredType)
          && convertedValue instanceof String) {
        TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor();
        if (elementTypeDesc != null) {
          Class<?> elementType = elementTypeDesc.getType();
          if (Class.class == elementType || Enum.class.isAssignableFrom(elementType)) {
            convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
          }
        }
      }
      if (editor == null) {
        editor = findDefaultEditor(requiredType);
      }
      convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
    }

    boolean standardConversion = false;

    if (requiredType != null) {
      // Try to apply some standard type conversion rules if appropriate.

      if (convertedValue != null) {
        if (Object.class == requiredType) {
          return (T) convertedValue;
        } else if (requiredType.isArray()) {
          // Array required -> apply appropriate conversion of elements.
          if (convertedValue instanceof String
              && Enum.class.isAssignableFrom(requiredType.getComponentType())) {
            convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
          }
          return (T)
              convertToTypedArray(convertedValue, propertyName, requiredType.getComponentType());
        } else if (convertedValue instanceof Collection) {
          // Convert elements to target type, if determined.
          convertedValue =
              convertToTypedCollection(
                  (Collection<?>) convertedValue, propertyName, requiredType, typeDescriptor);
          standardConversion = true;
        } else if (convertedValue instanceof Map) {
          // Convert keys and values to respective target type, if determined.
          convertedValue =
              convertToTypedMap(
                  (Map<?, ?>) convertedValue, propertyName, requiredType, typeDescriptor);
          standardConversion = true;
        }
        if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) {
          convertedValue = Array.get(convertedValue, 0);
          standardConversion = true;
        }
        if (String.class == requiredType
            && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) {
          // We can stringify any primitive value...
          return (T) convertedValue.toString();
        } else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) {
          if (conversionAttemptEx == null
              && !requiredType.isInterface()
              && !requiredType.isEnum()) {
            try {
              Constructor<T> strCtor = requiredType.getConstructor(String.class);
              return BeanUtils.instantiateClass(strCtor, convertedValue);
            } catch (NoSuchMethodException ex) {
              // proceed with field lookup
              if (logger.isTraceEnabled()) {
                logger.trace(
                    "No String constructor found on type [" + requiredType.getName() + "]", ex);
              }
            } catch (Exception ex) {
              if (logger.isDebugEnabled()) {
                logger.debug(
                    "Construction via String failed for type [" + requiredType.getName() + "]", ex);
              }
            }
          }
          String trimmedValue = ((String) convertedValue).trim();
          if (requiredType.isEnum() && "".equals(trimmedValue)) {
            // It's an empty enum identifier: reset the enum value to null.
            return null;
          }
          convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue);
          standardConversion = true;
        } else if (convertedValue instanceof Number
            && Number.class.isAssignableFrom(requiredType)) {
          convertedValue =
              NumberUtils.convertNumberToTargetClass(
                  (Number) convertedValue, (Class<Number>) requiredType);
          standardConversion = true;
        }
      } else {
        // convertedValue == null
        if (requiredType == Optional.class) {
          convertedValue = Optional.empty();
        }
      }

      if (!ClassUtils.isAssignableValue(requiredType, convertedValue)) {
        if (conversionAttemptEx != null) {
          // Original exception from former ConversionService call above...
          throw conversionAttemptEx;
        } else if (conversionService != null) {
          // ConversionService not tried before, probably custom editor found
          // but editor couldn't produce the required type...
          TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
          if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
            return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
          }
        }

        // Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
        StringBuilder msg = new StringBuilder();
        msg.append("Cannot convert value of type '")
            .append(ClassUtils.getDescriptiveType(newValue));
        msg.append("' to required type '")
            .append(ClassUtils.getQualifiedName(requiredType))
            .append("'");
        if (propertyName != null) {
          msg.append(" for property '").append(propertyName).append("'");
        }
        if (editor != null) {
          msg.append(": PropertyEditor [")
              .append(editor.getClass().getName())
              .append("] returned inappropriate value of type '")
              .append(ClassUtils.getDescriptiveType(convertedValue))
              .append("'");
          throw new IllegalArgumentException(msg.toString());
        } else {
          msg.append(": no matching editors or conversion strategy found");
          throw new IllegalStateException(msg.toString());
        }
      }
    }

    if (conversionAttemptEx != null) {
      if (editor == null
          && !standardConversion
          && requiredType != null
          && Object.class != requiredType) {
        throw conversionAttemptEx;
      }
      logger.debug(
          "Original ConversionService attempt failed - ignored since "
              + "PropertyEditor based conversion eventually succeeded",
          conversionAttemptEx);
    }

    return (T) convertedValue;
  }