public static T convert()

in core/src/main/java/com/jetbrains/youtrackdb/internal/core/metadata/schema/PropertyTypeInternal.java [1627:1739]


  public static <T> T convert(@Nullable DatabaseSessionInternal session, final Object value,
      Class<? extends T> targetClass) {
    if (value == null) {
      return null;
    }

    if (targetClass == null) {
      return (T) value;
    }

    if (value.getClass().equals(targetClass))
    // SAME TYPE: DON'T CONVERT IT
    {
      return (T) value;
    }

    if (targetClass.isAssignableFrom(value.getClass()))
    // COMPATIBLE TYPES: DON'T CONVERT IT
    {
      return (T) value;
    }

    try {
      if (byte[].class.isAssignableFrom(targetClass)) {
        return (T) BINARY.convert(value, null, null, session);
      } else if (byte[].class.isAssignableFrom(value.getClass())) {
        return (T) value;
      } else if (targetClass.equals(Byte.TYPE) || targetClass.equals(Byte.class)) {
        return (T) BYTE.convert(value, null, null, session);
      } else if (targetClass.equals(Short.TYPE) || targetClass.equals(Short.class)) {
        return (T) SHORT.convert(value, null, null, session);
      } else if (targetClass.equals(Integer.TYPE) || targetClass.equals(Integer.class)) {
        return (T) INTEGER.convert(value, null, null, session);
      } else if (targetClass.equals(Long.TYPE) || targetClass.equals(Long.class)) {
        return (T) LONG.convert(value, null, null, session);
      } else if (targetClass.equals(Float.TYPE) || targetClass.equals(Float.class)) {
        return (T) FLOAT.convert(value, null, null, session);
      } else if (targetClass.equals(BigDecimal.class)) {
        return (T) DECIMAL.convert(value, null, null, session);
      } else if (targetClass.equals(Double.TYPE) || targetClass.equals(Double.class)) {
        return (T) DOUBLE.convert(value, null, null, session);
      } else if (targetClass.equals(Boolean.TYPE) || targetClass.equals(Boolean.class)) {
        return (T) BOOLEAN.convert(value, null, null, session);
      } else if (EntityLinkSetImpl.class.isAssignableFrom(targetClass)) {
        return (T) LINKSET.convert(value, null, null, session);
      } else if (Set.class.isAssignableFrom(targetClass)) {
        return (T) EMBEDDEDSET.convert(value, null, null, session);
      } else if (EntityLinkListImpl.class.isAssignableFrom(targetClass)) {
        return (T) LINKLIST.convert(value, null, null, session);
      } else if (Collection.class.isAssignableFrom(targetClass)) {
        return (T) EMBEDDEDLIST.convert(value, null, null, session);
      } else if (EntityLinkMapIml.class.isAssignableFrom(targetClass)) {
        return (T) LINKMAP.convert(value, null, null, session);
      } else if (Map.class.isAssignableFrom(targetClass)) {
        return (T) EMBEDDEDMAP.convert(value, null, null, session);
      } else if (targetClass.equals(Date.class)) {
        return (T) DATETIME.convert(value, null, null, session);
      } else if (targetClass.equals(String.class)) {
        return (T) STRING.convert(value, null, null, session);
      } else if (Identifiable.class.isAssignableFrom(targetClass)) {
        return (T) LINK.convert(value, null, null, session);
      } else if (targetClass.equals(LinkBag.class)) {
        return (T) LINKBAG.convert(value, null, null, session);
      }
    } catch (
        IllegalArgumentException e) {
      // PASS THROUGH
      throw BaseException.wrapException(
          new DatabaseException(session != null ? session.getDatabaseName() : null,
              String.format("Error in conversion of value '%s' to type '%s'", value, targetClass)),
          e, session.getDatabaseName());
    } catch (
        Exception e) {
      return switch (value) {
        case Collection collection when collection.size() == 1
            && !Collection.class.isAssignableFrom(targetClass) ->
          // this must be a comparison with the result of a subquery, try to unbox the collection
            convert(session, collection.iterator().next(), targetClass);
        case Result result when result.getPropertyNames().size() == 1
            && !Result.class.isAssignableFrom(targetClass) ->
          // try to unbox Result with a single property, for subqueries
            convert(session,
                result.getProperty(result.getPropertyNames().getFirst()),
                targetClass);
        case Entity entity when ((EntityImpl) value).getPropertyNames().size() == 1
            && !Entity.class.isAssignableFrom(targetClass) ->
          // try to unbox Result with a single property, for subqueries
            convert(session,
                entity
                    .getProperty(
                        ((EntityImpl) value).getPropertyNamesInternal(false,
                                true)
                            .getFirst()),
                targetClass);
        default -> throw BaseException.wrapException(
            new ValidationException(session != null ? session.getDatabaseName() : null,
                String.format("Error in conversion of value '%s' to type '%s'", value,
                    targetClass)),
            e, session.getDatabaseName());
      };
    }

    var type = getTypeByClass(targetClass);
    if (type != null) {
      var typeClass = type.javaDefaultType;
      if (typeClass != targetClass && typeClass.isAssignableFrom(targetClass)) {
        return (T) convert(session, value, typeClass);
      }
    }

    throw new DatabaseException(session != null ? session.getDatabaseName() : null,
        String.format("Error in conversion of value '%s' to type '%s'", value, targetClass));
  }