diff --git a/src/cli/java/org/commcare/util/screen/QueryScreen.java b/src/cli/java/org/commcare/util/screen/QueryScreen.java index ca18fcc855..80c95d3944 100644 --- a/src/cli/java/org/commcare/util/screen/QueryScreen.java +++ b/src/cli/java/org/commcare/util/screen/QueryScreen.java @@ -9,7 +9,6 @@ import com.google.common.collect.Multimap; -import org.commcare.cases.util.StringUtils; import org.commcare.core.encryption.CryptUtil; import org.commcare.core.interfaces.VirtualDataInstanceStorage; import org.commcare.data.xml.VirtualInstances; @@ -19,7 +18,6 @@ import org.commcare.session.RemoteQuerySessionManager; import org.commcare.suite.model.RemoteQueryDatum; import org.commcare.suite.model.QueryPrompt; -import org.javarosa.core.model.SelectChoice; import org.javarosa.core.model.instance.ExternalDataInstance; import org.javarosa.core.model.instance.ExternalDataInstanceSource; import org.javarosa.core.services.locale.Localization; @@ -33,7 +31,6 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.Map; -import java.util.Vector; import datadog.trace.api.Trace; @@ -149,10 +146,10 @@ public Pair processResponse(InputStream responseDa return instanceOrError; } - public void updateSession(ExternalDataInstance dataInstance) { + public void updateSession(ExternalDataInstance dataInstance, Multimap queryData) { if (dataInstance != null) { ExternalDataInstance userInputInstance = getUserInputInstance(); - sessionWrapper.setQueryDatum(dataInstance, userInputInstance); + sessionWrapper.setQueryDatum(dataInstance, userInputInstance, queryData); } } @@ -247,7 +244,7 @@ public boolean handleInputAndUpdateSession(CommCareSession session, String input Multimap requestData = getQueryParams(false); InputStream response = sessionUtils.makeQueryRequest(url, requestData, domainedUsername, password); Pair instanceOrError = processResponse(response, url, requestData); - updateSession(instanceOrError.first); + updateSession(instanceOrError.first, requestData); if (currentMessage != null) { out.println(currentMessage); } diff --git a/src/main/java/org/commcare/session/CommCareSession.java b/src/main/java/org/commcare/session/CommCareSession.java index 76b5cb7bcd..bdc7ede208 100644 --- a/src/main/java/org/commcare/session/CommCareSession.java +++ b/src/main/java/org/commcare/session/CommCareSession.java @@ -38,12 +38,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; -import java.util.Set; -import java.util.Stack; -import java.util.Vector; +import java.util.*; import javax.annotation.Nullable; @@ -505,15 +500,26 @@ public void setDatum(String type, String keyId, String value, ExternalDataInstan * Set a (xml) data instance as the result to a session query datum. * The instance is available in session's evaluation context until the corresponding query frame is removed */ - public void setQueryDatum(ExternalDataInstance queryResultInstance, ExternalDataInstance... extras) { + public void setQueryDatum(ExternalDataInstance queryResultInstance) { + setQueryDatum(queryResultInstance, null); + } + + public void setQueryDatum(ExternalDataInstance queryResultInstance, ExternalDataInstance instance) { + setQueryDatum(queryResultInstance, instance, null); + } + + public void setQueryDatum(ExternalDataInstance queryResultInstance, ExternalDataInstance instance, Multimap extras) { SessionDatum datum = getNeededDatum(); if (datum instanceof RemoteQueryDatum) { StackFrameStep step = new StackFrameStep( SessionFrame.STATE_QUERY_REQUEST, datum.getDataId(), datum.getValue()); step.addDataInstanceSource(queryResultInstance.getSource()); - for (ExternalDataInstance instance : extras) { + if (instance != null) { step.addDataInstanceSource(instance.getSource()); } + if (extras != null) { + extras.entries().forEach(entry -> step.addExtra(entry.getKey(), entry.getValue())); + } frame.pushStep(step); syncState(); } else { diff --git a/src/main/java/org/commcare/xml/StackFrameStepParser.java b/src/main/java/org/commcare/xml/StackFrameStepParser.java index e310aca99e..c920ee7c39 100644 --- a/src/main/java/org/commcare/xml/StackFrameStepParser.java +++ b/src/main/java/org/commcare/xml/StackFrameStepParser.java @@ -81,17 +81,16 @@ private StackFrameStep parseJump() throws InvalidStructureException, IOException } private StackFrameStep parseValue(String type, String datumId) throws XmlPullParserException, IOException, InvalidStructureException { - //TODO: ... require this to have a value!!!! It's not processing this properly String value = parser.getAttributeValue(null, "value"); boolean valueIsXpath; if (value == null) { //must have a child value = parser.nextText(); - //Can we get here, or would this have caused an exception? - if (value == null) { - throw new InvalidStructureException("Stack frame element must define a value expression or have a direct value", parser); - } else { + if (value != null) { value = value.trim(); + if (value.isEmpty()) { + value = null; + } } valueIsXpath = false; } else { diff --git a/src/test/java/org/commcare/xml/ParserTestUtils.java b/src/test/java/org/commcare/xml/ParserTestUtils.java index 17c72a313b..39f3cf5d27 100644 --- a/src/test/java/org/commcare/xml/ParserTestUtils.java +++ b/src/test/java/org/commcare/xml/ParserTestUtils.java @@ -12,7 +12,7 @@ */ public class ParserTestUtils { - public static T buildParser(String xml, Class parserClass) { + public static T buildParser(String xml, Class parserClass) { return buildParser(xml, (xmlParser) -> { try { Constructor constructor = parserClass.getConstructor(KXmlParser.class); @@ -23,7 +23,7 @@ public static T buildParser(String xml, Class< }); } - public static T buildParser(String xml, Function builder) { + public static T buildParser(String xml, Function builder) { try { ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.getBytes("UTF-8")); KXmlParser parser = ElementParser.instantiateParser(inputStream); diff --git a/src/test/java/org/commcare/xml/StackParserTest.java b/src/test/java/org/commcare/xml/StackParserTest.java new file mode 100644 index 0000000000..48f5f3f3fa --- /dev/null +++ b/src/test/java/org/commcare/xml/StackParserTest.java @@ -0,0 +1,26 @@ +package org.commcare.xml; + +import org.commcare.session.SessionFrame; +import org.commcare.suite.model.StackFrameStep; +import org.commcare.suite.model.StackOperation; +import org.javarosa.xml.util.InvalidStructureException; +import org.junit.Assert; +import org.junit.Test; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +public class StackParserTest { + + @Test + public void testParseRewind() throws IOException, InvalidStructureException, XmlPullParserException { + String xml = ""; + StackOpParser parser = ParserTestUtils.buildParser(xml, StackOpParser::new); + StackOperation op = parser.parse(); + Assert.assertEquals(StackOperation.OPERATION_PUSH, op.getOp()); + StackFrameStep steps = op.getStackFrameSteps().get(0); + Assert.assertEquals(steps.getElementType(), SessionFrame.STATE_REWIND); + System.out.println(steps.getValue()); + Assert.assertNull(steps.getValue()); + } +}