Skip to content

Commit

Permalink
finos#1296 casting/method signature improvements in SchemaMapper
Browse files Browse the repository at this point in the history
  • Loading branch information
junaidzm13 committed Apr 25, 2024
1 parent f4296fd commit e4591c7
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ private class ColumnValueParser(private val mapper: SchemaMapper) extends SqlFil
}

private def parseStringToColumnDataType(value: String): Either[ErrorMessage, Any] =
DataType.parseDataType(value, column.dataType)
DataType.parseToDataType(value, column.dataType)

private def convertColumnValueToExternalFieldType(columnValue: Any): Either[ErrorMessage, Any] =
mapper.toMappedExternalFieldType(columnValue, column.name)
mapper.toMappedExternalFieldType(column.name, columnValue)
.toRight(s"Failed to convert column value `$columnValue` from `${column.dataType}` to external type `${field.dataType}`")

private def convertExternalValueToString(v: Any): String =
mapper.convertExternalValueToString(v, field.name).getOrElse(logWarningAndUseDefaultToString(v))
private def convertExternalValueToString(value: Any): String =
mapper.convertExternalValueToString(field.name, value).getOrElse(logWarningAndUseDefaultToString(value))

private def logWarningAndUseDefaultToString(value: Any): String = {
logger.warn(
Expand Down
2 changes: 1 addition & 1 deletion vuu/src/main/scala/org/finos/vuu/core/table/Column.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ object DataType {
}
}

def parseDataType[T](value: String, t: Class[T]): Either[String, T] = {
def parseToDataType[T](value: String, t: Class[T]): Either[String, T] = {
typeConverterContainer.convert[String, T](value, classOf[String], t) match {
case Some(parsedValue) => Right(parsedValue)
case None => Left(s"Failed to parse String $value to data type $t")
Expand Down
31 changes: 19 additions & 12 deletions vuu/src/main/scala/org/finos/vuu/util/schema/SchemaMapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import org.finos.vuu.util.schema.typeConversion.{TypeConverter, TypeConverterCon
trait SchemaMapper {
def tableColumn(extFieldName: String): Option[Column]
def externalSchemaField(columnName: String): Option[SchemaField]
def toMappedExternalFieldType(columnValue: Any, columnName: String): Option[Any]
def toMappedInternalColumnType(extFieldValue: Any, extFieldName: String): Option[Any]
def convertExternalValueToString(externalValue: Any, extFieldName: String): Option[String]
def toMappedExternalFieldType(columnName: String, columnValue: Any): Option[Any]
def toMappedInternalColumnType(extFieldName: String, extFieldValue: Any): Option[Any]
def convertExternalValueToString(extFieldName: String, extFieldValue: Any): Option[String]
def toInternalRowMap(externalValues: List[_]): Map[String, Any]
def toInternalRowMap(externalDto: Product): Map[String, Any]
}
Expand Down Expand Up @@ -116,7 +116,7 @@ object SchemaMapper {
.map({ case (t1, t2) => s"[ ${TypeConverter.buildConverterName(t1, t2)} ]" })
.mkString("\n")

Option(errorStr).filter(_.nonEmpty).map("Following `TypeConverter` are required but not found:\n" + _)
Option(errorStr).filter(_.nonEmpty).map("Following `TypeConverter`s are required but not found:\n" + _)
}

private def extFieldToColMap(extSchema: ExternalEntitySchema, columns: Array[Column], fieldsMap: Map[String, String]): Map[SchemaField, Column] = {
Expand Down Expand Up @@ -146,28 +146,35 @@ private class SchemaMapperImpl(private val externalSchema: ExternalEntitySchema,
private def toInternalRowMap(externalValues: Array[_]): Map[String, Any] = {
externalFieldByColumnName.map({ case (columnName, extField) =>
val extFieldValue = externalValues(extField.index)
val columnValue = toMappedInternalColumnType(extFieldValue, extField.name).get
// remove this get and make this return Optional (need to guard against conversion error if a user sends in a value not matching the schema type)
val columnValue = toMappedInternalColumnType(extField.name, extFieldValue).get
(columnName, columnValue)
})
}

override def toMappedExternalFieldType(columnValue: Any, columnName: String): Option[Any] = {
override def toMappedExternalFieldType(columnName: String, columnValue: Any): Option[Any] = {
externalSchemaField(columnName).map(field => {
val col = tableColumn(field.name).get
typeConverterContainer.convert(columnValue, col.dataType.asInstanceOf[Class[Any]], field.dataType)
castToAny(col.dataType).flatMap(typeConverterContainer.convert(columnValue, _, field.dataType))
})
}

override def toMappedInternalColumnType(extFieldValue: Any, extFieldName: String): Option[Any] = {
override def toMappedInternalColumnType(extFieldName: String, extFieldValue: Any): Option[Any] = {
tableColumn(extFieldName).map(col => {
val field = externalSchemaField(col.name).get
typeConverterContainer.convert(extFieldValue, field.dataType.asInstanceOf[Class[Any]], col.dataType)
castToAny(field.dataType).flatMap(typeConverterContainer.convert(extFieldValue, _, col.dataType))
})
}

override def convertExternalValueToString(externalValue: Any, extFieldName: String): Option[String] = {
extFieldsMap.get(extFieldName)
.flatMap(f => typeConverterContainer.convert(externalValue, f.dataType.asInstanceOf[Class[Any]], classOf[String]))
override def convertExternalValueToString(extFieldName: String, extFieldValue: Any): Option[String] = {
extFieldsMap.get(extFieldName).flatMap(
f => castToAny(f.dataType).flatMap(typeConverterContainer.convert(extFieldValue, _, classOf[String]))
)
}

private def castToAny(cls: Class[_]): Option[Class[Any]] = cls match {
case c: Class[Any] => Some(c)
case _ => None
}

private def getExternalSchemaFieldsByColumnName =
Expand Down

0 comments on commit e4591c7

Please sign in to comment.