Skip to content

Instantly share code, notes, and snippets.

@esabook
Last active November 25, 2019 15:48
Show Gist options
  • Save esabook/2fc5524edefe7dc9531de958b7620681 to your computer and use it in GitHub Desktop.
Save esabook/2fc5524edefe7dc9531de958b7620681 to your computer and use it in GitHub Desktop.
Process custom PreloadType to xForm (ODK Collect)
package org.odk.collect.android.logic;
import android.support.annotation.NonNull;
import com.google.common.base.Joiner;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.data.LongData;
import org.javarosa.core.model.data.StringData;
import org.javarosa.core.model.instance.TreeElement;
import org.javarosa.core.model.utils.IPreloadHandler;
import org.javarosa.core.model.utils.QuestionPreloader;
import java.util.ArrayList;
import java.util.List;
/**
* Process custom xForm (ODK Collect), because no official prepared
* this rule is to record total time, with additional time-frame (time-laps)
*
* https://opendatakit.github.io/xforms-spec/#bind-attributes
* | PreloadType | Type | Name |Note |
* | ----------- | ---- | ---------- |----------------------------------------------------|
* | timer | long | timerTotal |total time in millis, e.g. 1000 |
* | timer | string| timerLaps |array of session recorded, e.g. 1-2;5-1000;8000-8100|
*
* Example in xml:
* `jr:preload="timer"`
* `jr:preloadParams="timerTotal" type="long"`
* `jr:preloadParams="timerLaps" type="string"`
*
* usage:
* final FormDef formDef = createFormDefFromCacheOrXml(formPath, formXml);
* formDef.setPreloader(new CollectQuestionPreloader());
*
* ..........................
* // validate current session, sync persist data
* getFormController().getFormDef().postProcessInstance();
*
* // store and save new value to xForm
* CollectQuestionPreloader.setNewTimerTotal(passTimeMilis[0]);
* CollectQuestionPreloader.getNewTimerLaps().add(String.format("%s-%s", startTimeMilis, Calendar.getInstance().getTimeInMillis()));
*
* // validate again to force sync current data to be stored to persist
* getFormController().getFormDef().postProcessInstance();
**/
public class CollectQuestionPreloader extends QuestionPreloader {
public static boolean isOldTimerTotalUpdated;
private static long OldTimerTotal;
private static long newTimerTotal;
private static List<String> newTimerLaps = new ArrayList<>();
IPreloadHandler timerLoader = new IPreloadHandler() {
@Override
public String preloadHandled() {
return "timer";
}
@Override
public IAnswerData handlePreload(String preloadParams) {
return "timerTotal".equals(preloadParams)
? new LongData(CollectQuestionPreloader.newTimerTotal)
: "timerLaps".equals(preloadParams)
? new StringData(getNewTimeLapsString())
: null;
}
@Override
public boolean handlePostProcess(TreeElement node, String params) {
if (params.contains("timer")) {
if ("timerLaps".equals(params)) {
String oldValue = node.getValue() == null
? null
: node.getValue().getValue().toString();
boolean hasNewVlue = CollectQuestionPreloader.getNewTimerLaps().size() > 0;
String newValue = hasNewVlue
? oldValue == null || oldValue.equals("")
? getNewTimeLapsString()
: oldValue.concat(";").concat(getNewTimeLapsString())
: oldValue;
node.setAnswer(newValue == null
? null
: new StringData(newValue));
CollectQuestionPreloader.getNewTimerLaps().clear();
} else if ("timerTotal".equals(params)) {
long oldValue = node.getValue() == null ? 0 : (long) node.getValue().getValue();
CollectQuestionPreloader.OldTimerTotal = oldValue;
CollectQuestionPreloader.isOldTimerTotalUpdated = true;
long newValue = oldValue + CollectQuestionPreloader.newTimerTotal;
node.setAnswer(new LongData(newValue));
CollectQuestionPreloader.newTimerTotal = 0;
}
return true;
} else {
return false;
}
}
@NonNull
String getNewTimeLapsString() {
return Joiner.on(";").skipNulls().join(CollectQuestionPreloader.getNewTimerLaps());
}
};
/**
*
*/
public CollectQuestionPreloader() {
super.addPreloadHandler(timerLoader);
}
public static long getOldTimerTotal() {
return CollectQuestionPreloader.OldTimerTotal;
}
public static void setNewTimerTotal(long timerTotal) {
CollectQuestionPreloader.newTimerTotal = timerTotal;
}
public static List<String> getNewTimerLaps() {
return CollectQuestionPreloader.newTimerLaps;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment