All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.molgenis.data.DataConverter Maven / Gradle / Ivy

There is a newer version: 8.4.5
Show newest version
package org.molgenis.data;

import static com.google.common.collect.Streams.stream;
import static java.lang.String.format;
import static java.util.Collections.emptyList;

import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.molgenis.data.meta.AttributeType;
import org.molgenis.data.meta.model.Attribute;
import org.molgenis.util.ApplicationContextProvider;
import org.molgenis.util.ListEscapeUtils;
import org.molgenis.util.UnexpectedEnumException;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;

public class DataConverter {
  private static ConversionService conversionService;

  private DataConverter() {}

  /** @throws ConversionException if convertion failed or no converter was found */
  @SuppressWarnings("unchecked")
  @Nullable
  @CheckForNull
  private static  T convert(@Nullable @CheckForNull Object source, Class targetType) {
    if (source == null) {
      return null;
    }

    if (targetType.isAssignableFrom(source.getClass())) {
      return (T) source;
    }

    try {
      return getConversionService().convert(source, targetType);
    } catch (ConversionException e) {
      throw new DataConversionException(e);
    }
  }

  /**
   * Convert value to the type based on the given attribute.
   *
   * @param source value to convert
   * @param attr attribute that defines the type of the converted value
   * @return converted value or the input value if the attribute type is a reference type
   * @throws AttributeValueConversionException if conversion failed
   */
  public static Object convert(Object source, Attribute attr) {
    try {
      return convert(source, attr.getDataType());
    } catch (DataConversionException e) {
      throw new AttributeValueConversionException(
          format(
              "Conversion failure in entity type [%s] attribute [%s]; %s",
              attr.getEntity().getId(), attr.getName(), e.getMessage()),
          e);
    }
  }

  private static Object convert(Object source, AttributeType attributeType) {
    Object value;
    switch (attributeType) {
      case BOOL:
        value = toBoolean(source);
        break;
      case XREF:
      case CATEGORICAL:
      case CATEGORICAL_MREF:
      case MREF:
      case FILE:
      case ONE_TO_MANY:
        value = source;
        break;
      case COMPOUND:
        throw new UnsupportedOperationException();
      case DATE:
        value = toLocalDate(source);
        break;
      case DATE_TIME:
        value = toInstant(source);
        break;
      case DECIMAL:
        value = toDouble(source);
        break;
      case INT:
        value = toInt(source);
        break;
      case LONG:
        value = toLong(source);
        break;
      case EMAIL:
      case ENUM:
      case HTML:
      case HYPERLINK:
      case SCRIPT:
      case STRING:
      case TEXT:
        value = toString(source);
        break;
      default:
        throw new UnexpectedEnumException(attributeType);
    }
    return value;
  }

  /** @throws DataConversionException if conversion failed */
  @Nullable
  @CheckForNull
  public static String toString(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof String) {
      return (String) source;
    }
    if (source instanceof Iterable) {
      StringBuilder sb = new StringBuilder();
      for (Object obj : (Iterable) source) {
        if (sb.length() > 0) sb.append(",");
        sb.append(toString(obj));
      }

      return sb.toString();
    }
    return convert(source, String.class);
  }

  /** @throws DataConversionException if conversion failed */
  @Nullable
  @CheckForNull
  public static Integer toInt(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof Integer) {
      return (Integer) source;
    }
    return convert(source, Integer.class);
  }

  /** @throws DataConversionException if conversion failed */
  @Nullable
  @CheckForNull
  public static Long toLong(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof Long) {
      return (Long) source;
    }
    return convert(source, Long.class);
  }

  /**
   * @return true, false or null
   * @throws DataConversionException if conversion failed
   */
  @SuppressWarnings("squid:S2447") // null is a valid return value
  @Nullable
  @CheckForNull
  public static Boolean toBoolean(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof Boolean) {
      return (Boolean) source;
    }
    return convert(source, Boolean.class);
  }

  /** @throws DataConversionException if conversion failed */
  @Nullable
  @CheckForNull
  public static Double toDouble(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof Double) {
      return (Double) source;
    }
    return convert(source, Double.class);
  }

  /** @throws DataConversionException if conversion failed */
  @Nullable
  @CheckForNull
  public static LocalDate toLocalDate(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof LocalDate) {
      return (LocalDate) source;
    }
    return convert(source, LocalDate.class);
  }

  /** @throws DataConversionException if conversion failed */
  @Nullable
  @CheckForNull
  public static Instant toInstant(@Nullable @CheckForNull Object source) {
    if (source == null) {
      return null;
    }
    if (source instanceof Instant) {
      return (Instant) source;
    }
    return convert(source, Instant.class);
  }

  /** @throws DataConversionException if conversion failed */
  public static List toList(@Nullable @CheckForNull Object source) {
    List stringList;
    if (source == null) {
      stringList = emptyList();
    } else if (source instanceof Iterable) {
      Iterable iterable = (Iterable) source;
      stringList = stream(iterable).map(DataConverter::toString).collect(Collectors.toList());
    } else if (source instanceof String) {
      String string = (String) source;
      stringList = ListEscapeUtils.toList(string);
    } else {
      stringList = ListEscapeUtils.toList(source.toString());
    }
    return stringList;
  }

  /** testability */
  public static void setConversionService(ConversionService conversionService) {
    DataConverter.conversionService = conversionService;
  }

  private static ConversionService getConversionService() {
    if (conversionService == null) {
      conversionService =
          ApplicationContextProvider.getApplicationContext().getBean(ConversionService.class);
    }
    return conversionService;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy