package org.commcare.activities.components; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Pair; import java.io.File; import java.text.SimpleDateFormat; import java.util.Calendar; import org.commcare.activities.FormEntryActivity; import org.commcare.models.ODKStorage; import org.commcare.provider.FormsProviderAPI; import org.commcare.provider.InstanceProviderAPI; import org.commcare.utils.FileUtil; /** * Tracks the current form instance's xml file and auxilary files (multimedia) * * @author Phillip Mates (pmates@dimagi.com) */ public class FormEntryInstanceState { public static final String KEY_INSTANCEDESTINATION = "instancedestination"; // Identifies the gp of the form used to launch form entry private static final String KEY_FORMPATH = "formpath"; // Path to a particular form instance public static String mInstancePath; private String mInstanceDestination; private String mFormPath; /** * 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(Context context, Uri instanceProviderContentURI) { // default to false if we're mid form boolean complete = false; // Then see if we've already marked this form as complete before String selection = InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH + "=?"; String[] selectionArgs = { mInstancePath }; Cursor c = null; try { c = context.getContentResolver().query(instanceProviderContentURI, null, selection, selectionArgs, null); if (c != null && c.getCount() > 0) { c.moveToFirst(); String status = c.getString(c.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS)); if (InstanceProviderAPI.STATUS_COMPLETE.compareTo(status) == 0) { complete = true; } } } finally { if (c != null) { c.close(); } } return complete; } public static Pair<Uri, Boolean> getInstanceUri(Context context, Uri uri, Uri formProviderContentURI, FormEntryInstanceState instanceState) throws FormEntryActivity.FormQueryException { Cursor instanceCursor = null; Cursor formCursor = null; Boolean isInstanceReadOnly = false; Uri formUri = null; try { instanceCursor = context.getContentResolver().query(uri, null, null, null, null); if (instanceCursor == null) { throw new FormEntryActivity.FormQueryException("Bad URI: resolved to null"); } else if (instanceCursor.getCount() != 1) { throw new FormEntryActivity.FormQueryException("Bad URI: " + uri); } else { instanceCursor.moveToFirst(); mInstancePath = instanceCursor.getString(instanceCursor .getColumnIndex(InstanceProviderAPI.InstanceColumns.INSTANCE_FILE_PATH)); final String jrFormId = instanceCursor.getString(instanceCursor .getColumnIndex(InstanceProviderAPI.InstanceColumns.JR_FORM_ID)); //If this form is both already completed if (InstanceProviderAPI.STATUS_COMPLETE.equals(instanceCursor.getString(instanceCursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.STATUS)))) { if (!Boolean.parseBoolean(instanceCursor.getString(instanceCursor.getColumnIndex(InstanceProviderAPI.InstanceColumns.CAN_EDIT_WHEN_COMPLETE)))) { isInstanceReadOnly = true; } } final String[] selectionArgs = { jrFormId }; final String selection = FormsProviderAPI.FormsColumns.JR_FORM_ID + " like ?"; formCursor = context.getContentResolver().query(formProviderContentURI, null, selection, selectionArgs, null); if (formCursor == null || formCursor.getCount() < 1) { throw new FormEntryActivity.FormQueryException("Parent form does not exist"); } else if (formCursor.getCount() == 1) { formCursor.moveToFirst(); instanceState.setFormPath( formCursor.getString(formCursor .getColumnIndex(FormsProviderAPI.FormsColumns.FORM_FILE_PATH))); formUri = ContentUris.withAppendedId(formProviderContentURI, formCursor.getLong(formCursor.getColumnIndex(FormsProviderAPI.FormsColumns._ID))); } else if (formCursor.getCount() > 1) { throw new FormEntryActivity.FormQueryException("More than one possible parent form"); } } } finally { if (instanceCursor != null) { instanceCursor.close(); } if (formCursor != null) { formCursor.close(); } } return new Pair<>(formUri, isInstanceReadOnly); } /** * Get the default title for ODK's "Form title" field */ public static String getDefaultFormTitle(Context context, Intent intent) { String saveName = FormEntryActivity.mFormController.getFormTitle(); if (InstanceProviderAPI.InstanceColumns.CONTENT_ITEM_TYPE.equals(context.getContentResolver().getType(intent.getData()))) { Uri instanceUri = intent.getData(); Cursor instance = null; try { instance = context.getContentResolver().query(instanceUri, null, null, null, null); if (instance != null && instance.getCount() == 1) { instance.moveToFirst(); saveName = instance.getString(instance .getColumnIndex(InstanceProviderAPI.InstanceColumns.DISPLAY_NAME)); } } finally { if (instance != null) { instance.close(); } } } return saveName; } public void saveState(Bundle outState) { outState.putString(KEY_INSTANCEDESTINATION, mInstanceDestination); outState.putString(KEY_FORMPATH, mFormPath); } public void loadState(Bundle savedInstanceState) { if (savedInstanceState.containsKey(KEY_INSTANCEDESTINATION)) { mInstanceDestination = savedInstanceState.getString(KEY_INSTANCEDESTINATION); } if (savedInstanceState.containsKey(KEY_FORMPATH)) { mFormPath = savedInstanceState.getString(KEY_FORMPATH); } } public void loadFromIntent(Intent intent) { if (intent.hasExtra(KEY_INSTANCEDESTINATION)) { this.mInstanceDestination = intent.getStringExtra(KEY_INSTANCEDESTINATION); } else { mInstanceDestination = ODKStorage.INSTANCES_PATH; } } public String getFormPath() { return mFormPath; } public void initInstancePath() { // Create new answer folder. String time = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss") .format(Calendar.getInstance().getTime()); String file = mFormPath.substring(mFormPath.lastIndexOf(File.separator) + 1, mFormPath.lastIndexOf('.')); String path = mInstanceDestination + file + "_" + time; if (FileUtil.createFolder(path)) { FormEntryInstanceState.mInstancePath = path + File.separator + file + "_" + time + ".xml"; } } public void setFormPath(String path) { mFormPath = path; } public static String getInstanceFolder() { return mInstancePath.substring(0, mInstancePath.lastIndexOf(File.separator) + 1); } }