use of org.odk.collect.android.dao.InstancesDao in project collect by opendatakit.
the class InstanceSyncTask method doInBackground.
@Override
protected String doInBackground(Void... params) {
int instance = ++counter;
Timber.i("[%d] doInBackground begins!", instance);
currentStatus = Collect.getInstance().getString(R.string.instance_scan_completed);
try {
List<String> candidateInstances = new LinkedList<String>();
File instancesPath = new File(Collect.INSTANCES_PATH);
if (instancesPath.exists() && instancesPath.isDirectory()) {
File[] instanceFolders = instancesPath.listFiles();
if (instanceFolders.length == 0) {
Timber.i("[%d] Empty instance folder. Stopping scan process.", instance);
return currentStatus;
}
// Build the list of potential path that we need to add to the content provider
for (File instanceDir : instanceFolders) {
File instanceFile = new File(instanceDir, instanceDir.getName() + ".xml");
if (instanceFile.exists() && instanceFile.canRead()) {
candidateInstances.add(instanceFile.getAbsolutePath());
} else {
Timber.i("[%d] Ignoring: %s", instance, instanceDir.getAbsolutePath());
}
}
Collections.sort(candidateInstances);
List<String> filesToRemove = new ArrayList<>();
// Remove all the path that's already in the content provider
Cursor instanceCursor = null;
try {
String sortOrder = InstanceColumns.INSTANCE_FILE_PATH + " ASC ";
instanceCursor = Collect.getInstance().getContentResolver().query(InstanceColumns.CONTENT_URI, null, null, null, sortOrder);
if (instanceCursor == null) {
Timber.e("[%d] Instance content provider returned null", instance);
return currentStatus;
}
instanceCursor.moveToPosition(-1);
while (instanceCursor.moveToNext()) {
String instanceFilename = instanceCursor.getString(instanceCursor.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH));
String instanceStatus = instanceCursor.getString(instanceCursor.getColumnIndex(InstanceColumns.STATUS));
if (candidateInstances.contains(instanceFilename) || instanceStatus.equals(InstanceProviderAPI.STATUS_SUBMITTED)) {
candidateInstances.remove(instanceFilename);
} else {
filesToRemove.add(instanceFilename);
}
}
} finally {
if (instanceCursor != null) {
instanceCursor.close();
}
}
InstancesDao instancesDao = new InstancesDao();
instancesDao.deleteInstancesFromIDs(filesToRemove);
final boolean instanceSyncFlag = PreferenceManager.getDefaultSharedPreferences(Collect.getInstance().getApplicationContext()).getBoolean(PreferenceKeys.KEY_INSTANCE_SYNC, true);
int counter = 0;
// Begin parsing and add them to the content provider
for (String candidateInstance : candidateInstances) {
String instanceFormId = getFormIdFromInstance(candidateInstance);
// only process if we can find the id from the instance file
if (instanceFormId != null) {
Cursor formCursor = null;
try {
String selection = FormsColumns.JR_FORM_ID + " = ? ";
String[] selectionArgs = new String[] { instanceFormId };
// retrieve the form definition
formCursor = Collect.getInstance().getContentResolver().query(FormsColumns.CONTENT_URI, null, selection, selectionArgs, null);
// TODO: optimize this by caching unavailable form definition to skip
if (formCursor != null && formCursor.moveToFirst()) {
String submissionUri = null;
if (!formCursor.isNull(formCursor.getColumnIndex(FormsColumns.SUBMISSION_URI))) {
submissionUri = formCursor.getString(formCursor.getColumnIndex(FormsColumns.SUBMISSION_URI));
}
String jrFormId = formCursor.getString(formCursor.getColumnIndex(FormsColumns.JR_FORM_ID));
String jrVersion = formCursor.getString(formCursor.getColumnIndex(FormsColumns.JR_VERSION));
String formName = formCursor.getString(formCursor.getColumnIndex(FormsColumns.DISPLAY_NAME));
// add missing fields into content values
ContentValues values = new ContentValues();
values.put(InstanceColumns.INSTANCE_FILE_PATH, candidateInstance);
values.put(InstanceColumns.SUBMISSION_URI, submissionUri);
values.put(InstanceColumns.DISPLAY_NAME, formName);
values.put(InstanceColumns.JR_FORM_ID, jrFormId);
values.put(InstanceColumns.JR_VERSION, jrVersion);
values.put(InstanceColumns.STATUS, instanceSyncFlag ? InstanceProviderAPI.STATUS_COMPLETE : InstanceProviderAPI.STATUS_INCOMPLETE);
values.put(InstanceColumns.CAN_EDIT_WHEN_COMPLETE, Boolean.toString(true));
// save the new instance object
Collect.getInstance().getContentResolver().insert(InstanceColumns.CONTENT_URI, values);
counter++;
}
} finally {
if (formCursor != null) {
formCursor.close();
}
}
}
}
if (counter > 0) {
currentStatus += String.format(Collect.getInstance().getString(R.string.instance_scan_count), counter);
}
}
} finally {
Timber.i("[%d] doInBackground ends!", instance);
}
return currentStatus;
}
use of org.odk.collect.android.dao.InstancesDao in project collect by opendatakit.
the class InstanceUploaderActivity method uploadingComplete.
@Override
public void uploadingComplete(HashMap<String, String> result) {
Timber.i("uploadingComplete: Processing results (%d) from upload of %d instances!", result.size(), instancesToSend.length);
try {
dismissDialog(PROGRESS_DIALOG);
} catch (Exception e) {
// tried to close a dialog not open. don't care.
}
Set<String> keys = result.keySet();
Iterator<String> it = keys.iterator();
StringBuilder message = new StringBuilder();
int count = keys.size();
while (count > 0) {
String[] selectionArgs = null;
if (count > ApplicationConstants.SQLITE_MAX_VARIABLE_NUMBER) {
selectionArgs = new String[ApplicationConstants.SQLITE_MAX_VARIABLE_NUMBER];
} else {
selectionArgs = new String[count];
}
StringBuilder selection = new StringBuilder();
selection.append(InstanceColumns._ID + " IN (");
int i = 0;
while (it.hasNext() && i < selectionArgs.length) {
selectionArgs[i] = it.next();
selection.append("?");
if (i != selectionArgs.length - 1) {
selection.append(",");
}
i++;
}
selection.append(")");
count -= selectionArgs.length;
StringBuilder queryMessage = new StringBuilder();
Cursor results = null;
try {
results = new InstancesDao().getInstancesCursor(selection.toString(), selectionArgs);
if (results.getCount() > 0) {
results.moveToPosition(-1);
while (results.moveToNext()) {
String name = results.getString(results.getColumnIndex(InstanceColumns.DISPLAY_NAME));
String id = results.getString(results.getColumnIndex(InstanceColumns._ID));
String text = localizeDefaultAggregateSuccessfulText(result.get(id));
queryMessage.append(name).append(" - ").append(text).append("\n\n");
}
}
} catch (SQLException e) {
Timber.e(e);
} finally {
if (results != null) {
results.close();
}
}
message.append(queryMessage.toString());
}
if (message.length() == 0) {
message.append(getString(R.string.no_forms_uploaded));
}
if (!isInstanceStateSaved()) {
createUploadInstancesResultDialog(message.toString().trim());
} else {
finish();
}
}
use of org.odk.collect.android.dao.InstancesDao in project collect by opendatakit.
the class InstanceUploaderList method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
Timber.i("onCreate");
setContentView(R.layout.instance_uploader_list);
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
showAllMode = savedInstanceState.getBoolean(SHOW_ALL_MODE);
}
instancesDao = new InstancesDao();
uploadButton = findViewById(R.id.upload_button);
uploadButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = connectivityManager.getActiveNetworkInfo();
if (NetworkReceiver.running) {
ToastUtils.showShortToast(R.string.send_in_progress);
} else if (ni == null || !ni.isConnected()) {
logger.logAction(this, "uploadButton", "noConnection");
ToastUtils.showShortToast(R.string.no_connection);
} else {
int checkedItemCount = getCheckedCount();
logger.logAction(this, "uploadButton", Integer.toString(checkedItemCount));
if (checkedItemCount > 0) {
// items selected
uploadSelectedFiles();
setAllToCheckedState(listView, false);
toggleButtonLabel(findViewById(R.id.toggle_button), listView);
uploadButton.setEnabled(false);
} else {
// no items selected
ToastUtils.showLongToast(R.string.noselect_error);
}
}
}
});
final Button toggleSelsButton = findViewById(R.id.toggle_button);
toggleSelsButton.setLongClickable(true);
toggleSelsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ListView lv = listView;
boolean allChecked = toggleChecked(lv);
toggleButtonLabel(toggleSelsButton, lv);
uploadButton.setEnabled(allChecked);
if (!allChecked) {
selectedInstances.clear();
}
}
});
toggleSelsButton.setOnLongClickListener(this);
setupAdapter();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemsCanFocus(false);
listView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
uploadButton.setEnabled(areCheckedItems());
}
});
// set title
setTitle(getString(R.string.send_data));
instanceSyncTask = new InstanceSyncTask();
instanceSyncTask.setDiskSyncListener(this);
instanceSyncTask.execute();
sortingOptions = new String[] { getString(R.string.sort_by_name_asc), getString(R.string.sort_by_name_desc), getString(R.string.sort_by_date_asc), getString(R.string.sort_by_date_desc) };
}
use of org.odk.collect.android.dao.InstancesDao 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;
}
use of org.odk.collect.android.dao.InstancesDao in project collect by opendatakit.
the class ExternalAppsUtils method populateParameters.
public static void populateParameters(Intent intent, Map<String, String> exParams, TreeReference reference) throws ExternalParamsException {
FormDef formDef = Collect.getInstance().getFormController().getFormDef();
FormInstance formInstance = formDef.getInstance();
EvaluationContext evaluationContext = new EvaluationContext(formDef.getEvaluationContext(), reference);
if (exParams != null) {
for (Map.Entry<String, String> paramEntry : exParams.entrySet()) {
String paramEntryValue = paramEntry.getValue();
try {
Object result;
if (paramEntryValue.startsWith("'")) {
// but not require an ending quote
if (paramEntryValue.endsWith("'")) {
result = paramEntryValue.substring(1, paramEntryValue.length() - 1);
} else {
result = paramEntryValue.substring(1, paramEntryValue.length());
}
} else if (paramEntryValue.startsWith("/")) {
// treat this is an xpath
XPathPathExpr pathExpr = XPathReference.getPathExpr(paramEntryValue);
XPathNodeset xpathNodeset = pathExpr.eval(formInstance, evaluationContext);
result = XPathFuncExpr.unpack(xpathNodeset);
} else if (paramEntryValue.equals("instanceProviderID()")) {
// instanceProviderID returns -1 if the current instance has not been
// saved to disk already
String path = Collect.getInstance().getFormController().getInstanceFile().getAbsolutePath();
String instanceProviderID = "-1";
Cursor c = new InstancesDao().getInstancesCursorForFilePath(path);
if (c != null && c.getCount() > 0) {
// should only ever be one
c.moveToFirst();
instanceProviderID = c.getString(c.getColumnIndex(InstanceColumns._ID));
}
if (c != null) {
c.close();
}
result = instanceProviderID;
} else {
// treat this is a function
XPathExpression xpathExpression = XPathParseTool.parseXPath(paramEntryValue);
result = xpathExpression.eval(formInstance, evaluationContext);
}
if (result != null && result instanceof Serializable) {
intent.putExtra(paramEntry.getKey(), (Serializable) result);
}
} catch (Exception e) {
throw new ExternalParamsException("Could not evaluate '" + paramEntryValue + "'", e);
}
}
}
}
Aggregations