use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class SaveToDiskTask method exportData.
/**
* Write's the data to the sdcard, and updates the instances content provider.
* In theory we don't have to write to disk, and this is where you'd add
* other methods.
*/
private void exportData(boolean markCompleted) throws IOException, EncryptionException {
FormController formController = Collect.getInstance().getFormController();
publishProgress(Collect.getInstance().getString(R.string.survey_saving_collecting_message));
ByteArrayPayload payload = formController.getFilledInFormXml();
// write out xml
String instancePath = formController.getInstanceFile().getAbsolutePath();
publishProgress(Collect.getInstance().getString(R.string.survey_saving_saving_message));
exportXmlFile(payload, instancePath);
// update the uri. We have exported the reloadable instance, so update status...
// Since we saved a reloadable instance, it is flagged as re-openable so that if any error
// occurs during the packaging of the data for the server fails (e.g., encryption),
// we can still reopen the filled-out form and re-save it at a later time.
updateInstanceDatabase(true, true);
if (markCompleted) {
// now see if the packaging of the data for the server would make it
// non-reopenable (e.g., encryption or send an SMS or other fraction of the form).
boolean canEditAfterCompleted = formController.isSubmissionEntireForm();
boolean isEncrypted = false;
// build a submission.xml to hold the data being submitted
// and (if appropriate) encrypt the files on the side
// pay attention to the ref attribute of the submission profile...
File instanceXml = formController.getInstanceFile();
File submissionXml = new File(instanceXml.getParentFile(), "submission.xml");
payload = formController.getSubmissionXml();
// write out submission.xml -- the data to actually submit to aggregate
publishProgress(Collect.getInstance().getString(R.string.survey_saving_finalizing_message));
exportXmlFile(payload, submissionXml.getAbsolutePath());
// see if the form is encrypted and we can encrypt it...
EncryptedFormInformation formInfo = EncryptionUtils.getEncryptedFormInformation(uri, formController.getSubmissionMetadata());
if (formInfo != null) {
// if we are encrypting, the form cannot be reopened afterward
canEditAfterCompleted = false;
// and encrypt the submission (this is a one-way operation)...
publishProgress(Collect.getInstance().getString(R.string.survey_saving_encrypting_message));
EncryptionUtils.generateEncryptedSubmission(instanceXml, submissionXml, formInfo);
isEncrypted = true;
}
// At this point, we have:
// 1. the saved original instanceXml,
// 2. all the plaintext attachments
// 2. the submission.xml that is the completed xml (whether encrypting or not)
// 3. all the encrypted attachments if encrypting (isEncrypted = true).
//
// NEXT:
// 1. Update the instance database (with status complete).
// 2. Overwrite the instanceXml with the submission.xml
// and remove the plaintext attachments if encrypting
updateInstanceDatabase(false, canEditAfterCompleted);
if (!canEditAfterCompleted) {
// delete the restore Xml file.
if (!instanceXml.delete()) {
String msg = "Error deleting " + instanceXml.getAbsolutePath() + " prior to renaming submission.xml";
Timber.e(msg);
throw new IOException(msg);
}
// rename the submission.xml to be the instanceXml
if (!submissionXml.renameTo(instanceXml)) {
String msg = "Error renaming submission.xml to " + instanceXml.getAbsolutePath();
Timber.e(msg);
throw new IOException(msg);
}
} else {
// (we don't need to delete and rename anything).
if (!submissionXml.delete()) {
String msg = "Error deleting " + submissionXml.getAbsolutePath() + " (instance is re-openable)";
Timber.w(msg);
}
}
// (anything not named instanceXml or anything not ending in .enc)
if (isEncrypted) {
if (!EncryptionUtils.deletePlaintextFiles(instanceXml)) {
Timber.e("Error deleting plaintext files for %s", instanceXml.getAbsolutePath());
}
}
}
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class ODKView method setDataForFields.
public void setDataForFields(Bundle bundle) throws JavaRosaException {
if (bundle == null) {
return;
}
FormController formController = Collect.getInstance().getFormController();
Set<String> keys = bundle.keySet();
for (String key : keys) {
for (QuestionWidget questionWidget : widgets) {
FormEntryPrompt prompt = questionWidget.getFormEntryPrompt();
TreeReference treeReference = (TreeReference) prompt.getFormElement().getBind().getReference();
if (treeReference.getNameLast().equals(key)) {
switch(prompt.getDataType()) {
case Constants.DATATYPE_TEXT:
formController.saveAnswer(prompt.getIndex(), ExternalAppsUtils.asStringData(bundle.get(key)));
break;
case Constants.DATATYPE_INTEGER:
formController.saveAnswer(prompt.getIndex(), ExternalAppsUtils.asIntegerData(bundle.get(key)));
break;
case Constants.DATATYPE_DECIMAL:
formController.saveAnswer(prompt.getIndex(), ExternalAppsUtils.asDecimalData(bundle.get(key)));
break;
default:
throw new RuntimeException(getContext().getString(R.string.ext_assign_value_error, treeReference.toString(false)));
}
break;
}
}
}
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class ItemsetWidget method getItems.
private List<SelectChoice> getItems() {
String nodesetString = getNodesetString();
List<String> arguments = new ArrayList<>();
String selectionString = getSelectionStringAndPopulateArguments(getQueryString(nodesetString), arguments);
FormController formController = Collect.getInstance().getFormController();
String[] selectionArgs = getSelectionArgs(arguments, nodesetString, formController);
return selectionArgs == null ? null : getItemsFromDatabase(selectionString, selectionArgs, formController);
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class QuestionWidget method clearNextLevelsOfCascadingSelect.
/**
* It's needed only for external choices. Everything works well and
* out of the box when we use internal choices instead
*/
protected void clearNextLevelsOfCascadingSelect() {
FormController formController = Collect.getInstance().getFormController();
if (formController == null) {
return;
}
if (formController.currentCaptionPromptIsQuestion()) {
try {
FormIndex startFormIndex = formController.getQuestionPrompt().getIndex();
formController.stepToNextScreenEvent();
while (formController.currentCaptionPromptIsQuestion() && formController.getQuestionPrompt().getFormElement().getAdditionalAttribute(null, "query") != null) {
formController.saveAnswer(formController.getQuestionPrompt().getIndex(), null);
formController.stepToNextScreenEvent();
}
formController.jumpToIndex(startFormIndex);
} catch (JavaRosaException e) {
Timber.d(e);
}
}
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class InstancesDaoHelper method isInstanceComplete.
/**
* Checks the database to determine if the current instance being edited has
* already been 'marked completed'. A form can be 'unmarked' complete and
* then resaved.
*
* @return true if form has been marked completed, false otherwise.
*/
public static boolean isInstanceComplete(boolean end) {
// default to false if we're mid form
boolean complete = false;
FormController formController = Collect.getInstance().getFormController();
if (formController != null && formController.getInstanceFile() != null) {
// First check if we're at the end of the form, then check the preferences
complete = end && (boolean) GeneralSharedPreferences.getInstance().get(PreferenceKeys.KEY_COMPLETED_DEFAULT);
// Then see if we've already marked this form as complete before
String path = formController.getInstanceFile().getAbsolutePath();
try (Cursor c = new InstancesDao().getInstancesCursorForFilePath(path)) {
if (c != null && c.getCount() > 0) {
c.moveToFirst();
int columnIndex = c.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS);
String status = c.getString(columnIndex);
if (InstanceProviderAPI.STATUS_COMPLETE.equals(status)) {
complete = true;
}
}
}
} else {
Timber.w("FormController or its instanceFile field has a null value");
}
return complete;
}
Aggregations