diff --git a/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java b/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java index c8d4ef47f..0050fe637 100644 --- a/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java +++ b/src/main/java/org/javarosa/entities/internal/EntityFormParseProcessor.java @@ -14,12 +14,14 @@ public class EntityFormParseProcessor implements BindAttributeProcessor, FormDefProcessor { + private static final String ENTITIES_NAMESPACE = "http://www.opendatakit.org/xforms/entities"; + private final List> saveTos = new ArrayList<>(); @Override - public Set getUsedAttributes() { - HashSet attributes = new HashSet<>(); - attributes.add("saveto"); + public Set> getUsedAttributes() { + HashSet> attributes = new HashSet<>(); + attributes.add(new Pair<>(ENTITIES_NAMESPACE, "saveto")); return attributes; } diff --git a/src/main/java/org/javarosa/xform/parse/BindAttributeProcessor.java b/src/main/java/org/javarosa/xform/parse/BindAttributeProcessor.java index bcd028a7f..df51b7cca 100644 --- a/src/main/java/org/javarosa/xform/parse/BindAttributeProcessor.java +++ b/src/main/java/org/javarosa/xform/parse/BindAttributeProcessor.java @@ -1,12 +1,13 @@ package org.javarosa.xform.parse; +import kotlin.Pair; import org.javarosa.core.model.DataBinding; import java.util.Set; public interface BindAttributeProcessor { - Set getUsedAttributes(); + Set> getUsedAttributes(); void processBindingAttribute(String name, String value, DataBinding binding); } diff --git a/src/main/java/org/javarosa/xform/parse/StandardBindAttributesProcessor.java b/src/main/java/org/javarosa/xform/parse/StandardBindAttributesProcessor.java index 3b4555949..07020ab2d 100644 --- a/src/main/java/org/javarosa/xform/parse/StandardBindAttributesProcessor.java +++ b/src/main/java/org/javarosa/xform/parse/StandardBindAttributesProcessor.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import kotlin.Pair; import org.javarosa.core.model.DataBinding; import org.javarosa.core.model.FormDef; import org.javarosa.core.model.IDataReference; @@ -118,8 +119,10 @@ DataBinding createBinding(IXFormParserFunctions parserFunctions, FormDef formDef bindAttributeProcessors.stream().forEach(bindAttributeProcessor -> { for (int i = 0; i < element.getAttributeCount(); i++) { + String namespace = element.getAttributeNamespace(i); String name = element.getAttributeName(i); - if (bindAttributeProcessor.getUsedAttributes().contains(name)) { + + if (bindAttributeProcessor.getUsedAttributes().contains(new Pair<>(namespace, name))) { bindAttributeProcessor.processBindingAttribute(name, element.getAttributeValue(i), binding); } } @@ -127,7 +130,7 @@ DataBinding createBinding(IXFormParserFunctions parserFunctions, FormDef formDef List processorAttributes = bindAttributeProcessors.stream() .flatMap((Function>) bindAttributeProcessor -> { - return bindAttributeProcessor.getUsedAttributes().stream(); + return bindAttributeProcessor.getUsedAttributes().stream().map(Pair::getSecond); }) .collect(Collectors.toList()); diff --git a/src/test/java/org/javarosa/entities/internal/EntityFormParseProcessorTest.java b/src/test/java/org/javarosa/entities/internal/EntityFormParseProcessorTest.java new file mode 100644 index 000000000..3e26d49d4 --- /dev/null +++ b/src/test/java/org/javarosa/entities/internal/EntityFormParseProcessorTest.java @@ -0,0 +1,65 @@ +package org.javarosa.entities.internal; + +import kotlin.Pair; +import org.javarosa.core.model.FormDef; +import org.javarosa.core.util.XFormsElement; +import org.javarosa.xform.parse.XFormParser; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +import static java.util.Arrays.asList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.javarosa.core.util.BindBuilderXFormsElement.bind; +import static org.javarosa.core.util.XFormsElement.body; +import static org.javarosa.core.util.XFormsElement.head; +import static org.javarosa.core.util.XFormsElement.input; +import static org.javarosa.core.util.XFormsElement.mainInstance; +import static org.javarosa.core.util.XFormsElement.model; +import static org.javarosa.core.util.XFormsElement.t; +import static org.javarosa.core.util.XFormsElement.title; + +public class EntityFormParseProcessorTest { + + @Test + public void saveTosWithIncorrectNamespaceAreIgnored() throws IOException { + XFormsElement form = XFormsElement.html( + asList( + new Pair<>("correct", "http://www.opendatakit.org/xforms/entities"), + new Pair<>("incorrect", "blah") + ), + head( + title("Create entity form"), + model( + mainInstance( + t("data id=\"create-entity-form\"", + t("name"), + t("orx:meta", + t("correct:entity dataset=\"people\"", + t("correct:create") + ) + ) + ) + ), + bind("/data/name").type("string").withAttribute("incorrect", "saveto", "name") + ) + ), + body( + input("/data/name") + ) + ); + + EntityFormParseProcessor processor = new EntityFormParseProcessor(); + + XFormParser parser = new XFormParser(new InputStreamReader(new ByteArrayInputStream(form.asXml().getBytes()))); + parser.addBindAttributeProcessor(processor); + parser.addFormDefProcessor(processor); + + FormDef formDef = parser.parse(null); + assertThat(formDef.getExtras().get(EntityFormExtra.class).getSaveTos(), is(empty())); + } +} \ No newline at end of file