Skip to content

Commit

Permalink
decompose function into two
Browse files Browse the repository at this point in the history
  • Loading branch information
faberf committed Oct 14, 2024
1 parent 1c25dfa commit 11606d0
Showing 1 changed file with 66 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ val logger: KLogger = KotlinLogging.logger {}

private val NON_ALPHANUMERIC_REGEX = Regex("[^a-zA-Z0-9]")


private val DATE_FORMAT_PATTERNS = listOf(
"yyyy:MM:dd HH:mm:ss",
"yyyy-MM-dd HH:mm:ss",
Expand All @@ -45,65 +44,57 @@ private fun convertDate(date: String): Date? {
return null
}


private fun convertType(directory: Directory, tagType: Int, type: Type): Value<*>? = when (type) {
Type.Boolean -> Value.Boolean(directory.getBoolean(tagType))
Type.Byte -> Value.Byte(directory.getObject(tagType) as Byte)
Type.Datetime -> convertDate(directory.getString(tagType))?.let { Value.DateTime(it) }
Type.Double -> Value.Double(directory.getDouble(tagType))
Type.Float -> Value.Float(directory.getFloat(tagType))
Type.Int -> Value.Int(directory.getInt(tagType))
Type.Long -> Value.Long(directory.getLong(tagType))
Type.Short -> Value.Short(directory.getObject(tagType) as Short)
Type.String -> Value.String(directory.getString(tagType))
Type.Text -> Value.String(directory.getString(tagType))
Type.UUID -> Value.UUIDValue(UUID.fromString(directory.getString(tagType)))
is Type.BooleanVector -> throw IllegalArgumentException("Unsupported type: $type")
is Type.DoubleVector -> throw IllegalArgumentException("Unsupported type: $type")
is Type.FloatVector -> throw IllegalArgumentException("Unsupported type: $type")
is Type.IntVector -> throw IllegalArgumentException("Unsupported type: $type")
is Type.LongVector -> throw IllegalArgumentException("Unsupported type: $type")
}

private fun JsonElement.convertType(type: Type): Value<*>? {
fun JsonElement.toValue(): Value<*>? {
return when (this) {
is JsonPrimitive -> {
if (this.isString) {
when (type) {
Type.String -> Value.String(this.content)
Type.Text -> Value.String(this.content)
Type.Datetime -> convertDate(this.content)?.let { Value.DateTime(it) }
else -> null
}
} else {
when (type) {
Type.Boolean -> this.booleanOrNull?.let { Value.Boolean(it) }
Type.Byte -> this.intOrNull?.let { Value.Byte(it.toByte()) }
Type.Short -> this.intOrNull?.let { Value.Short(it.toShort()) }
Type.Int -> this.intOrNull?.let { Value.Int(it) }
Type.Long -> this.longOrNull?.let { Value.Long(it) }
Type.Float -> this.floatOrNull?.let { Value.Float(it) }
Type.Double -> this.doubleOrNull?.let { Value.Double(it) }
else -> null
}
}
}
is JsonObject, is JsonArray -> {
when (type) {
Type.Text -> Value.String(this.toString())
Type.String -> Value.String(this.toString())
Type.UUID -> Value.UUIDValue(UUID.fromString(this.toString()))
else -> throw IllegalArgumentException("Cannot convert non-primitive JsonElement to type $type")
when {
this.booleanOrNull != null -> Value.Boolean(this.boolean)
this.intOrNull != null -> Value.Int(this.int)
this.longOrNull != null -> Value.Long(this.long)
this.floatOrNull != null -> Value.Float(this.float)
this.doubleOrNull != null -> Value.Double(this.double)
this.isString -> Value.String(this.content) // Only isString exists
else -> null
}
}
else -> {
throw IllegalStateException("Unsupported JsonElement type")
}
is JsonArray, is JsonObject -> Value.String(this.toString())
else -> null
}
}

class ExifMetadataExtractor(input: Operator<Retrievable>, analyser: ExifMetadata, field: Schema.Field<ContentElement<*>, AnyMapStructDescriptor>?, parameters: Map<String,String>) : AbstractExtractor<ContentElement<*>, AnyMapStructDescriptor>(input, analyser, field, parameters) {
fun Value<*>.convertToType(type: Type): Value<*>? {
return when (type) {
Type.Boolean -> if (this is Value.Boolean) this else null
Type.Byte -> if (this is Value.Int) Value.Byte(this.value.toByte()) else null
Type.Short -> if (this is Value.Int) Value.Short(this.value.toShort()) else null
Type.Int -> if (this is Value.Int) this else null
Type.Long -> if (this is Value.Long) this else null
Type.Float -> if (this is Value.Float) this else null
Type.Double -> if (this is Value.Double) this else null
Type.String -> if (this is Value.String) this else null

Type.Text -> if (this is Value.String) {
Value.Text(this.value)
} else null

Type.Datetime -> if (this is Value.String) {
convertDate(this.value)?.let { Value.DateTime(it) }
} else null

Type.UUID -> if (this is Value.String) {
Value.UUIDValue(UUID.fromString(this.value))
} else null

else -> null
}
}

class ExifMetadataExtractor(
input: Operator<Retrievable>,
analyser: ExifMetadata,
field: Schema.Field<ContentElement<*>, AnyMapStructDescriptor>?,
parameters: Map<String, String>
) : AbstractExtractor<ContentElement<*>, AnyMapStructDescriptor>(input, analyser, field, parameters) {

override fun matches(retrievable: Retrievable): Boolean =
retrievable.filteredAttribute(SourceAttribute::class.java)?.source is FileSource
Expand All @@ -113,22 +104,23 @@ class ExifMetadataExtractor(input: Operator<Retrievable>, analyser: ExifMetadata
val columnValues = mutableMapOf<AttributeName, Value<*>>()

val attributes = this.field?.parameters?.map { (k, v) -> k to Attribute(k, Type.valueOf(v)) }?.toMap() ?: emptyMap()

for (directory in metadata.directories) {
for (tag in directory.tags) {
val tagname = tag.tagName.replace(NON_ALPHANUMERIC_REGEX, "")
val fullname = "${directory.name.replace(NON_ALPHANUMERIC_REGEX, "")}_$tagname"

if (fullname == "ExifSubIFD_UserComment" || fullname == "JpegComment_JPEGComment") {
if (fullname in attributes){
if (fullname in attributes) {
columnValues[fullname] = Value.String(tag.description)
}
try {
val json = Json.parseToJsonElement(tag.description).jsonObject
json.forEach { (key, value) ->
attributes[key]?.let { attribute ->
value.convertType(attribute.type)?.let { converted ->
columnValues[key] = converted
}
val jsonElement = Json.parseToJsonElement(tag.description)
val jsonValue = jsonElement.toValue()
val attribute = attributes[fullname]
if (attribute != null && jsonValue != null) {
jsonValue.convertToType(attribute.type)?.let { converted ->
columnValues[fullname] = converted
}
}
} catch (e: SerializationException) {
Expand All @@ -140,7 +132,6 @@ class ExifMetadataExtractor(input: Operator<Retrievable>, analyser: ExifMetadata
columnValues[fullname] = converted
}
}

}
}
}
Expand All @@ -149,3 +140,18 @@ class ExifMetadataExtractor(input: Operator<Retrievable>, analyser: ExifMetadata
return listOf(AnyMapStructDescriptor(UUID.randomUUID(), retrievable.id, attributes.values.toList(), columnValues.mapValues { it.value }, field = this.field))
}
}

private fun convertType(directory: Directory, tagType: Int, type: Type): Value<*>? = when (type) {
Type.Boolean -> Value.Boolean(directory.getBoolean(tagType))
Type.Byte -> Value.Byte(directory.getObject(tagType) as Byte)
Type.Datetime -> convertDate(directory.getString(tagType))?.let { Value.DateTime(it) }
Type.Double -> Value.Double(directory.getDouble(tagType))
Type.Float -> Value.Float(directory.getFloat(tagType))
Type.Int -> Value.Int(directory.getInt(tagType))
Type.Long -> Value.Long(directory.getLong(tagType))
Type.Short -> Value.Short(directory.getObject(tagType) as Short)
Type.String -> Value.String(directory.getString(tagType))
Type.Text -> Value.Text(directory.getString(tagType)) // Ensure Type.Text returns Value.Text
Type.UUID -> Value.UUIDValue(UUID.fromString(directory.getString(tagType)))
is Type.BooleanVector, is Type.DoubleVector, is Type.FloatVector, is Type.IntVector, is Type.LongVector -> throw IllegalArgumentException("Unsupported type: $type")
}

0 comments on commit 11606d0

Please sign in to comment.