Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import org.javarosa.xform.parse.XFormParserFactory
import org.javarosa.xform.util.XFormUtils
import org.odk.collect.android.dynamicpreload.DynamicPreloadXFormParserFactory
import org.odk.collect.android.logic.actions.setgeopoint.CollectSetGeopointActionHandler
import org.odk.collect.android.preferences.SettingsExt.getExperimentalOptIn
import org.odk.collect.android.projects.ProjectsDataService
import org.odk.collect.entities.javarosa.intance.LocalEntitiesExternalInstanceParserFactory
import org.odk.collect.entities.javarosa.parse.EntityXFormParserFactory
import org.odk.collect.entities.storage.EntitiesRepository
import org.odk.collect.metadata.PropertyManager
import org.odk.collect.projects.ProjectDependencyFactory
import org.odk.collect.settings.SettingsProvider
import org.odk.collect.settings.keys.ProjectKeys

class JavaRosaInitializer(
private val propertyManager: PropertyManager,
Expand Down Expand Up @@ -45,7 +47,7 @@ class JavaRosaInitializer(
val entityXFormParserFactory =
EntityXFormParserFactory(
XFormParserFactory()
)
) { settingsProvider.getUnprotectedSettings().getExperimentalOptIn(ProjectKeys.KEY_ENTITIES_SPEC_V2025_1) }
val dynamicPreloadXFormParserFactory =
DynamicPreloadXFormParserFactory(entityXFormParserFactory)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ object Defaults {
// experimental_preferences.xml
hashMap[ProjectKeys.KEY_DEBUG_FILTERS] = BuildConfig.BUILD_TYPE == "selfSignedRelease"
hashMap[ProjectKeys.KEY_ZXING_SCANNING] = false
hashMap[ProjectKeys.KEY_ENTITIES_SPEC_V2025_1] = false
return hashMap
}

Expand Down
5 changes: 5 additions & 0 deletions collect_app/src/main/res/xml/experimental_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
app:allowDividerBelow="false"
app:iconSpaceReserved="false">

<SwitchPreferenceCompat
android:key="entities_spec_v2025_1"
android:title="@string/entities_spec_v2025_1"
app:iconSpaceReserved="false" />

<Preference
android:key="entities"
android:title="@string/entity_browser_button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ import org.javarosa.xform.parse.XFormParser.BindAttributeProcessor
import org.javarosa.xform.parse.XFormParser.FormDefProcessor
import org.javarosa.xform.parse.XFormParser.MissingModelAttributeException
import org.javarosa.xform.parse.XFormParser.ModelAttributeProcessor
import org.odk.collect.entities.BuildConfig
import org.odk.collect.entities.javarosa.parse.EntityFormParseProcessor.Companion.VERSIONS.V2022_1
import org.odk.collect.entities.javarosa.parse.EntityFormParseProcessor.Companion.VERSIONS.V2023_1
import org.odk.collect.entities.javarosa.parse.EntityFormParseProcessor.Companion.VERSIONS.V2024_1
import org.odk.collect.entities.javarosa.parse.EntityFormParseProcessor.Companion.VERSIONS.V2025_1
import org.odk.collect.entities.javarosa.spec.EntityFormParser
import org.odk.collect.entities.javarosa.spec.UnrecognizedEntityVersionException

class EntityFormParseProcessor : BindAttributeProcessor, FormDefProcessor, ModelAttributeProcessor {
class EntityFormParseProcessor(
private val v2025enabled: () -> Boolean
) : BindAttributeProcessor, FormDefProcessor, ModelAttributeProcessor {
private val saveTos = mutableListOf<Pair<XPathReference, String>>()
private var version: String? = null

Expand All @@ -28,7 +29,7 @@ class EntityFormParseProcessor : BindAttributeProcessor, FormDefProcessor, Model
override fun processModelAttribute(name: String, value: String) {
version = value

if (BuildConfig.DEBUG && value.startsWith(V2025_1)) {
if (value.startsWith(V2025_1) && v2025enabled()) {
return
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.odk.collect.entities.javarosa.parse

import org.javarosa.xform.parse.IXFormParserFactory
import org.javarosa.xform.parse.XFormParser

class EntityXFormParserFactory(
base: IXFormParserFactory,
private val v2025enabled: () -> Boolean
) : IXFormParserFactory.Wrapper(base) {
override fun apply(parser: XFormParser): XFormParser {
val processor = EntityFormParseProcessor(v2025enabled)
parser.addProcessor(processor)

return parser
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

public class EntitiesTest {

private final EntityXFormParserFactory entityXFormParserFactory = new EntityXFormParserFactory(new XFormParserFactory());
private final EntityXFormParserFactory entityXFormParserFactory = new EntityXFormParserFactory(new XFormParserFactory(), () -> false);

@Before
public void setup() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

public class EntityFormFinalizationProcessorTest {

private final EntityXFormParserFactory entityXFormParserFactory = new EntityXFormParserFactory(new XFormParserFactory());
private final EntityXFormParserFactory entityXFormParserFactory = new EntityXFormParserFactory(new XFormParserFactory(), () -> false);

@Before
public void setup() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void whenVersionIsMissing_parsesWithoutError() throws XFormParser.ParseEx
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor();
EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);
parser.parse(null);
Expand Down Expand Up @@ -84,7 +84,7 @@ public void whenVersionIsMissing_andThereIsAnEntityElement_throwsException() {
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor();
EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);

Expand Down Expand Up @@ -125,7 +125,7 @@ public void whenVersionIsNotRecognized_throwsException() throws XFormParser.Pars
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor();
EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);
parser.parse(null);
Expand Down Expand Up @@ -158,7 +158,7 @@ public void whenVersionIsNewPatch_parsesCorrectly() throws XFormParser.ParseExce
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor();
EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);

Expand Down Expand Up @@ -193,7 +193,7 @@ public void whenVersionIsNewVersionWithUpdates_parsesCorrectly() throws XFormPar
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor();
EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);

Expand Down Expand Up @@ -227,11 +227,79 @@ public void saveTosWithIncorrectNamespaceAreIgnored() throws XFormParser.ParseEx
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor();
EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);

FormDef formDef = parser.parse(null);
assertThat(formDef.getExtras().get(EntityFormExtra.class).getSaveTos(), is(empty()));
}

@Test
public void whenVersionIs2025_1_andFeatureIsEnabled_parsesCorrectly() throws XFormParser.ParseException {
String updateVersion = "2025.1.0";

XFormsElement form = XFormsElement.html(
asList(
new Pair<>("entities", "http://www.opendatakit.org/xforms/entities")
),
head(
title("Create entity form"),
model(asList(new Pair<>("entities:entities-version", updateVersion)),
mainInstance(
t("data id=\"update-entity-form\"",
t("name"),
t("meta",
t("entity dataset=\"people\" update=\"1\" id=\"17\"")
)
)
),
bind("/data/name").type("string").withAttribute("entities", "saveto", "name")
)
),
body(
input("/data/name")
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> true);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);

FormDef formDef = parser.parse(null);
assertThat(formDef, notNullValue());
}

@Test(expected = UnrecognizedEntityVersionException.class)
public void whenVersionIs2025_1_andFeatureIsDisabled_throwsException() throws XFormParser.ParseException {
String updateVersion = "2025.1.0";

XFormsElement form = XFormsElement.html(
asList(
new Pair<>("entities", "http://www.opendatakit.org/xforms/entities")
),
head(
title("Create entity form"),
model(asList(new Pair<>("entities:entities-version", updateVersion)),
mainInstance(
t("data id=\"update-entity-form\"",
t("name"),
t("meta",
t("entity dataset=\"people\" update=\"1\" id=\"17\"")
)
)
),
bind("/data/name").type("string").withAttribute("entities", "saveto", "name")
)
),
body(
input("/data/name")
)
);

EntityFormParseProcessor processor = new EntityFormParseProcessor(() -> false);
XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes())));
parser.addProcessor(processor);
parser.parse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ object ProjectKeys {
// experimental_preferences.xml
const val KEY_DEBUG_FILTERS = "experimental_debug_filters"
const val KEY_ZXING_SCANNING = "zxing_scanning"
const val KEY_ENTITIES_SPEC_V2025_1 = "entities_spec_v2025_1"

// values
const val PROTOCOL_SERVER = "odk_default"
Expand Down
3 changes: 2 additions & 1 deletion strings/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,8 @@
<!-- An entity is any person, place or thing that a form can be about. This title appears on an experimental settings screen to view entities managed in the current project. -->
<string name="entities_title">Entity lists</string>

<!-- Title for setting that controls whether local entity features are enabled or not -->
<!-- Title for setting that controls whether entities spec v2025.1 are enabled or not -->
<string name="entities_spec_v2025_1">Enable entities spec v2025.1</string>

<!-- Text for button that leads to browser for the user to view and manage entity lists -->
<string name="entity_browser_button">View entity lists</string>
Expand Down