Skip to content

Commit

Permalink
Add support for client action listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
lognaturel committed Feb 5, 2021
1 parent 36d1cc0 commit 30d8261
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/main/java/org/javarosa/core/model/CoreModelModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public class CoreModelModule implements IModule {
"org.javarosa.core.model.data.UncastData",
"org.javarosa.core.model.data.helper.BasicDataPointer",
"org.javarosa.core.model.actions.SetValueAction",
"org.javarosa.core.model.actions.setgeopoint.StubSetGeopointAction"
"org.javarosa.core.model.actions.setgeopoint.StubSetGeopointAction",
"org.javarosa.core.model.actions.recordaudio.RecordAudioAction"
};

@Override
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/org/javarosa/core/model/actions/Actions.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.javarosa.core.model.actions;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.javarosa.core.model.actions.recordaudio.RecordAudioActionHandler;
import org.javarosa.core.model.actions.recordaudio.XFormsActionListener;

public class Actions {
private Actions() { }
Expand Down Expand Up @@ -41,11 +45,35 @@ private Actions() { }
private static final String[] TOP_LEVEL_EVENTS = new String[]{EVENT_ODK_INSTANCE_FIRST_LOAD, EVENT_ODK_INSTANCE_LOAD, EVENT_XFORMS_READY,
EVENT_XFORMS_REVALIDATE};

/**
* Global registry of client classes that want to get updates about triggered actions. Addresses the need for some
* actions to be handled entirely client-side.
*/
private static Map<String, XFormsActionListener> actionListeners = new HashMap<>();

public static boolean isValidEvent(String actionEventAttribute) {
return Arrays.asList(ALL_EVENTS).contains(actionEventAttribute);
}

public static boolean isTopLevelEvent(String actionEventAttribute) {
return Arrays.asList(TOP_LEVEL_EVENTS).contains(actionEventAttribute);
}


public static void registerActionListener(String actionName, XFormsActionListener listener) {
if (!actionName.equals(RecordAudioActionHandler.ELEMENT_NAME)){
throw new IllegalArgumentException("Currently, only the recordaudio action notifies listeners");
}

actionListeners.put(actionName, listener);
}

public static void unregisterActionListener(String actionName) {
actionListeners.remove(actionName);
}

public static XFormsActionListener getActionListener(String actionName) {
return actionListeners.get(actionName);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import org.javarosa.core.model.FormDef;
import org.javarosa.core.model.actions.Action;
import org.javarosa.core.model.actions.Actions;
import org.javarosa.core.model.instance.TreeReference;

public class RecordAudioAction extends Action {
private TreeReference targetReference;

public RecordAudioAction(TreeReference targetReference) {
super(RecordAudioActionHandler.ELEMENT_NAME);
this.targetReference = targetReference;
}

Expand All @@ -20,6 +22,10 @@ public TreeReference processAction(FormDef model, TreeReference contextRef) {
TreeReference contextualizedTargetReference = contextRef == null ? this.targetReference
: this.targetReference.contextualize(contextRef);

if (Actions.getActionListener(getName()) != null) {
Actions.getActionListener(getName()).actionTriggered(getName(), contextualizedTargetReference);
}

return contextualizedTargetReference;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.javarosa.core.model.actions.recordaudio;

import org.javarosa.core.model.instance.TreeReference;

public interface XFormsActionListener {
void actionTriggered(String actionName, TreeReference absoluteTargetRef);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.javarosa.core.model.actions;

import org.javarosa.core.model.actions.recordaudio.XFormsActionListener;
import org.javarosa.core.model.instance.TreeReference;

public class CapturingXFormsActionListener implements XFormsActionListener {
public String actionName;
public TreeReference absoluteTargetRef;

@Override
public void actionTriggered(String actionName, TreeReference absoluteTargetRef) {
this.actionName = actionName;
this.absoluteTargetRef = absoluteTargetRef;
}

public String getActionName() {
return actionName;
}

public TreeReference getAbsoluteTargetRef() {
return absoluteTargetRef;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.javarosa.core.test.Scenario.getRef;
import static org.javarosa.core.util.XFormsElement.body;
import static org.javarosa.core.util.XFormsElement.head;
import static org.javarosa.core.util.XFormsElement.html;
Expand All @@ -12,6 +13,7 @@
import static org.javarosa.core.util.XFormsElement.title;

import java.io.IOException;
import org.javarosa.core.model.actions.recordaudio.RecordAudioActionHandler;
import org.javarosa.core.test.Scenario;
import org.junit.Test;

Expand All @@ -35,4 +37,30 @@ public void recordAudioAction_isProcessedOnFormParse() throws IOException {

assertThat(scenario.getFormDef().hasAction("recordaudio"), is(true));
}

@Test
public void recordAudioAction_callsListenerActionTriggeredWhenTriggered() throws IOException {
CapturingXFormsActionListener listener = new CapturingXFormsActionListener();
Actions.registerActionListener(RecordAudioActionHandler.ELEMENT_NAME, listener);

Scenario.init("Record audio form", html(
head(
title("Record audio form"),
model(
mainInstance(
t("data id=\"record-audio-form\"",
t("recording"),
t("q1")
)),
t("odk:recordaudio event=\"odk-instance-load\" ref=\"/data/recording\""))),
body(
input("/data/q1")
)
));

assertThat(listener.getActionName(), is(RecordAudioActionHandler.ELEMENT_NAME));
assertThat(listener.getAbsoluteTargetRef(), is(getRef("/data/recording")));

Actions.unregisterActionListener(RecordAudioActionHandler.ELEMENT_NAME);
}
}

0 comments on commit 30d8261

Please sign in to comment.