Skip to content

Commit

Permalink
feature(core): update simplified representation in multi-attribute ca…
Browse files Browse the repository at this point in the history
…se with dataset (#1112)

* update simplified representation in multi-attribute case with dataset

* basic fixing

* added fixes and moved unit tests to CompactedEntityTests file

* modified baseline.xml file to fix exception

* added other attribute types in case of multi-instances

* chore: some renamings for a better understanding

* modified simplifyMultiInstanceAttribute method

* chore: indentations and misc cleanups

---------

Co-authored-by: Benoit Orihuela <[email protected]>
  • Loading branch information
ranim-n and bobeal authored Mar 21, 2024
1 parent 03034cc commit 890b19c
Show file tree
Hide file tree
Showing 5 changed files with 716 additions and 422 deletions.
2 changes: 1 addition & 1 deletion shared/config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<ManuallySuppressedIssues></ManuallySuppressedIssues>
<CurrentIssues>
<ID>CyclomaticComplexMethod:ExceptionHandler.kt$ExceptionHandler$@ExceptionHandler fun transformErrorResponse(throwable: Throwable): ResponseEntity&lt;ProblemDetail&gt;</ID>
<ID>LongMethod:ExpandedEntityTests.kt$ExpandedEntityTests$@Test fun `it should return simplified GeoJSON entities`()</ID>
<ID>LongMethod:CompactedEntityTests.kt$CompactedEntityTests$@Test fun `it should return the GeoJSON representation of simplified entities`()</ID>
<ID>LongMethod:QueryUtils.kt$private fun transformQQueryToSqlJsonPath( mainAttributePath: List&lt;ExpandedTerm&gt;, trailingAttributePath: List&lt;ExpandedTerm&gt;, operator: String, value: String )</ID>
<ID>LongParameterList:ApiResponses.kt$( body: String, count: Int, resourceUrl: String, paginationQuery: PaginationQuery, requestParams: MultiValueMap&lt;String, String&gt;, mediaType: MediaType, contexts: List&lt;String&gt; )</ID>
<ID>LongParameterList:ApiResponses.kt$( entities: Any, count: Int, resourceUrl: String, paginationQuery: PaginationQuery, requestParams: MultiValueMap&lt;String, String&gt;, mediaType: MediaType, contexts: List&lt;String&gt; )</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_JSON_TERM
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_OBJECT
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE_TERM
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_GEOPROPERTY_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_JSONPROPERTY_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_NONE_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SYSATTRS_TERMS

typealias CompactedEntity = Map<String, Any>
Expand All @@ -23,24 +22,36 @@ private fun simplifyRepresentation(value: Any): Any =
// an attribute with a single instance
is Map<*, *> -> simplifyValue(value as Map<String, Any>)
// an attribute with multiple instances
is List<*> -> value.map {
when (it) {
is Map<*, *> -> simplifyValue(it as Map<String, Any>)
is List<*> -> {
when (value.first()) {
is Map<*, *> -> simplifyMultiInstanceAttribute(value as List<Map<String, Any>>)
// we keep @context value as it is (List<String>)
else -> it
else -> value
}
}
// keep id, type and other non-reified properties as they are (typically string or list)
else -> value
}

private fun simplifyValue(value: Map<String, Any>): Any =
when (value[JSONLD_TYPE_TERM]) {
NGSILD_PROPERTY_TERM, NGSILD_GEOPROPERTY_TERM -> value.getOrDefault(JSONLD_VALUE_TERM, value)
NGSILD_JSONPROPERTY_TERM -> mapOf(JSONLD_JSON_TERM to value.getOrDefault(JSONLD_JSON_TERM, value))
NGSILD_RELATIONSHIP_TERM -> value.getOrDefault(JSONLD_OBJECT, value)
else -> value
private fun simplifyMultiInstanceAttribute(value: List<Map<String, Any>>): Map<String, Map<String, Any>> {
val datasetIds = value.map {
val datasetId = (it[NGSILD_DATASET_ID_TERM] as? String) ?: NGSILD_NONE_TERM
val datasetValue: Any = simplifyValue(it)
Pair(datasetId, datasetValue)
}
return mapOf(NGSILD_DATASET_TERM to datasetIds.toMap())
}

private fun simplifyValue(value: Map<String, Any>): Any {
val attributeCompactedType = AttributeCompactedType.forKey(value[JSONLD_TYPE_TERM] as String)!!
return when (attributeCompactedType) {
AttributeCompactedType.PROPERTY, AttributeCompactedType.GEOPROPERTY -> {
value.getOrDefault(JSONLD_VALUE_TERM, value)
}
AttributeCompactedType.JSONPROPERTY -> mapOf(JSONLD_JSON_TERM to value.getOrDefault(JSONLD_JSON_TERM, value))
AttributeCompactedType.RELATIONSHIP -> value.getOrDefault(JSONLD_OBJECT, value)
}
}

fun CompactedEntity.toGeoJson(geometryProperty: String): Map<String, Any?> {
val geometryAttributeContent = this[geometryProperty] as? Map<String, Any>
Expand Down Expand Up @@ -120,3 +131,15 @@ fun List<CompactedEntity>.toFinalRepresentation(
)
} else it
}

enum class AttributeCompactedType(val key: String) {
PROPERTY("Property"),
RELATIONSHIP("Relationship"),
GEOPROPERTY("GeoProperty"),
JSONPROPERTY("JsonProperty");

companion object {
fun forKey(key: String): AttributeCompactedType? =
entries.find { it.key == key }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ object JsonLdUtils {
const val JSONLD_CONTEXT = "@context"
const val NGSILD_SCOPE_TERM = "scope"
const val NGSILD_SCOPE_PROPERTY = "https://uri.etsi.org/ngsi-ld/$NGSILD_SCOPE_TERM"

const val NGSILD_NONE_TERM = "@none"
const val NGSILD_DATASET_TERM = "dataset"
val JSONLD_EXPANDED_ENTITY_SPECIFIC_MEMBERS = setOf(JSONLD_TYPE, NGSILD_SCOPE_PROPERTY)

// List of members that are part of a core entity base definition (i.e., without attributes)
Expand All @@ -90,6 +91,8 @@ object JsonLdUtils {
val NGSILD_GEO_PROPERTIES_TERMS =
setOf(NGSILD_LOCATION_TERM, NGSILD_OBSERVATION_SPACE_TERM, NGSILD_OPERATION_SPACE_TERM)
const val NGSILD_DATASET_ID_PROPERTY = "https://uri.etsi.org/ngsi-ld/datasetId"
const val NGSILD_DATASET_ID_TERM = "datasetId"

const val NGSILD_INSTANCE_ID_PROPERTY = "https://uri.etsi.org/ngsi-ld/instanceId"

const val NGSILD_SUBSCRIPTION_TERM = "Subscription"
Expand Down
Loading

0 comments on commit 890b19c

Please sign in to comment.