-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for pulldata with local entities #6451
Changes from all commits
63ded83
b463ad7
bed7c86
7eae24d
880a2e4
92c0a9c
19d52ad
471f015
9c2a5ca
78b30c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package org.odk.collect.entities.javarosa.filter | ||
|
||
import org.javarosa.core.model.condition.EvaluationContext | ||
import org.javarosa.core.model.condition.IFunctionHandler | ||
import org.javarosa.xpath.expr.XPathFuncExpr | ||
import org.odk.collect.entities.javarosa.intance.LocalEntitiesInstanceAdapter | ||
import org.odk.collect.entities.storage.EntitiesRepository | ||
|
||
class PullDataFunctionHandler( | ||
entitiesRepository: EntitiesRepository, | ||
private val fallback: IFunctionHandler? = null | ||
) : IFunctionHandler { | ||
|
||
private val instanceAdapter = LocalEntitiesInstanceAdapter(entitiesRepository) | ||
|
||
override fun getName(): String { | ||
return NAME | ||
} | ||
|
||
override fun getPrototypes(): List<Array<Class<Any>>> { | ||
return emptyList() | ||
} | ||
|
||
override fun rawArgs(): Boolean { | ||
return true | ||
} | ||
|
||
override fun realTime(): Boolean { | ||
return false | ||
} | ||
|
||
override fun eval(args: Array<Any>, ec: EvaluationContext): Any { | ||
val instanceId = XPathFuncExpr.toString(args[0]) | ||
val child = XPathFuncExpr.toString(args[1]) | ||
val filterChild = XPathFuncExpr.toString(args[2]) | ||
val filterValue = XPathFuncExpr.toString(args[3]) | ||
|
||
return if (instanceAdapter.supportsInstance(instanceId)) { | ||
instanceAdapter.queryEq(instanceId, filterChild, filterValue)!!.firstOrNull() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like queryEq can't return null values so we could update that function by removing |
||
?.getFirstChild(child)?.value?.value ?: "" | ||
} else { | ||
fallback?.eval(args, ec) ?: "" | ||
} | ||
} | ||
|
||
companion object { | ||
private const val NAME = "pulldata" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ class LocalEntitiesInstanceAdapter(private val entitiesRepository: EntitiesRepos | |
|
||
0.until(count).map { | ||
if (it == 0) { | ||
convertToElement(first, true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I wonder if we need that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
convertToElement(first) | ||
} else { | ||
TreeElement("item", it, true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I wonder if we need that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The partial concept is currently too general for something like that as any |
||
} | ||
|
@@ -33,62 +33,82 @@ class LocalEntitiesInstanceAdapter(private val entitiesRepository: EntitiesRepos | |
} | ||
} else { | ||
entitiesRepository.getEntities(instanceId).map { entity -> | ||
convertToElement(entity, false) | ||
convertToElement(entity) | ||
} | ||
} | ||
} | ||
|
||
fun queryEq(instanceId: String, child: String, value: String): List<TreeElement>? { | ||
return when { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can now simplify this by adding child
|
||
child == "name" -> { | ||
child == EntityItemElement.ID -> { | ||
val entity = entitiesRepository.getById( | ||
instanceId, | ||
value | ||
) | ||
|
||
if (entity != null) { | ||
listOf(convertToElement(entity, false)) | ||
listOf(convertToElement(entity)) | ||
} else { | ||
emptyList() | ||
} | ||
} | ||
|
||
!listOf(EntityItemElement.LABEL, EntityItemElement.VERSION).contains(child) -> { | ||
child == EntityItemElement.LABEL -> { | ||
filterAndConvertEntities(instanceId) { it.label == value } | ||
} | ||
|
||
child == EntityItemElement.VERSION -> { | ||
filterAndConvertEntities(instanceId) { it.version == value.toInt() } | ||
} | ||
|
||
child == EntityItemElement.TRUNK_VERSION -> { | ||
filterAndConvertEntities(instanceId) { it.trunkVersion == value.toInt() } | ||
} | ||
|
||
child == EntityItemElement.BRANCH_ID -> { | ||
filterAndConvertEntities(instanceId) { it.branchId == value } | ||
} | ||
|
||
else -> { | ||
val entities = entitiesRepository.getAllByProperty( | ||
instanceId, | ||
child, | ||
value | ||
) | ||
|
||
entities.map { convertToElement(it, false) } | ||
entities.map { convertToElement(it) } | ||
} | ||
|
||
else -> null | ||
} | ||
} | ||
|
||
private fun convertToElement(entity: Entity.Saved, partial: Boolean): TreeElement { | ||
private fun filterAndConvertEntities( | ||
list: String, | ||
filter: (Entity.Saved) -> Boolean | ||
): List<TreeElement> { | ||
val entities = entitiesRepository.getEntities(list) | ||
return entities.filter(filter).map { convertToElement(it) } | ||
} | ||
|
||
private fun convertToElement(entity: Entity.Saved): TreeElement { | ||
val name = TreeElement(EntityItemElement.ID) | ||
val label = TreeElement(EntityItemElement.LABEL) | ||
val version = TreeElement(EntityItemElement.VERSION) | ||
val trunkVersion = TreeElement(EntityItemElement.TRUNK_VERSION) | ||
val branchId = TreeElement(EntityItemElement.BRANCH_ID) | ||
|
||
if (!partial) { | ||
name.value = StringData(entity.id) | ||
version.value = StringData(entity.version.toString()) | ||
branchId.value = StringData(entity.branchId) | ||
name.value = StringData(entity.id) | ||
version.value = StringData(entity.version.toString()) | ||
branchId.value = StringData(entity.branchId) | ||
|
||
if (entity.label != null) { | ||
label.value = StringData(entity.label) | ||
} | ||
if (entity.label != null) { | ||
label.value = StringData(entity.label) | ||
} | ||
|
||
if (entity.trunkVersion != null) { | ||
trunkVersion.value = StringData(entity.trunkVersion.toString()) | ||
} | ||
if (entity.trunkVersion != null) { | ||
trunkVersion.value = StringData(entity.trunkVersion.toString()) | ||
} | ||
|
||
val item = TreeElement("item", entity.index, partial) | ||
val item = TreeElement("item", entity.index, false) | ||
item.addChild(name) | ||
item.addChild(label) | ||
item.addChild(version) | ||
|
@@ -97,11 +117,7 @@ class LocalEntitiesInstanceAdapter(private val entitiesRepository: EntitiesRepos | |
|
||
entity.properties.forEach { property -> | ||
val propertyElement = TreeElement(property.first) | ||
|
||
if (!partial) { | ||
propertyElement.value = StringData(property.second) | ||
} | ||
|
||
propertyElement.value = StringData(property.second) | ||
item.addChild(propertyElement) | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can move extracting
child
,filterChild
andfilterValue
down and call only ifinstanceAdapter.supportsInstance(instanceId)
returns true.