Example usage for android.database Cursor getColumnCount

List of usage examples for android.database Cursor getColumnCount

Introduction

In this page you can find the example usage for android.database Cursor getColumnCount.

Prototype

int getColumnCount();

Source Link

Document

Return total number of columns

Usage

From source file:com.ruesga.timelinechart.TimelineChartView.java

private void checkCursorIntegrity(Cursor c) {
    if (c.getCount() == 0) {
        return;/*from   w  w  w.  java  2  s  .  co  m*/
    }
    int columnCount = c.getColumnCount();
    if (columnCount < 1) {
        throw new IllegalArgumentException("Cursor must have at least 2 columns");
    }
    if (!isNumericColumnType(0, c)) {
        throw new IllegalArgumentException("Column 0 must be a timestamp (numeric type)");
    }
    for (int i = 1; i < columnCount; i++) {
        if (!isNumericColumnType(i, c)) {
            throw new IllegalArgumentException("All series must be a valid numeric type");
        }
    }
}

From source file:it.bradipao.berengar.DbTool.java

public static int db2xml(SQLiteDatabase mDB, File xmlFile) {
    // vars// w  w  w .j a v a2s  .c o m
    final String XML_DATABASE = "database";
    final String XML_DBNAME = "dbname";
    final String XML_TABLES = "tables";
    final String XML_TABLE = "table";
    final String XML_TABLENAME = "tablename";
    final String XML_TABLESQL = "tablesql";
    final String XML_COLSNAME = "colsname";
    final String XML_ROWS = "rows";
    final String XML_ROW = "r";
    final String XML_COL = "c";

    // tables list query and cursor
    int iTableNum = 0;
    FileWriter fw = null;
    BufferedWriter bw = null;
    XmlSerializer sr = Xml.newSerializer();

    String tblquery = "select * from sqlite_master";
    Cursor tblcur = mDB.rawQuery(tblquery, null);
    String rowquery = "";
    Cursor rowcur = null;

    // file writers
    try {
        fw = new FileWriter(xmlFile);
        bw = new BufferedWriter(fw);
        sr.setOutput(bw);
    } catch (FileNotFoundException e) {
        Log.e(LOGTAG, "error in db2gson file writers", e);
    } catch (IOException e) {
        Log.e(LOGTAG, "error in db2gson file writers", e);
    }
    // xml serializer

    try {
        // prepare xml document
        sr.startDocument("UTF-8", true);
        sr.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

        // start document
        sr.startTag("", XML_DATABASE);
        sr.startTag("", XML_DBNAME);
        sr.text(xmlFile.getName());
        sr.endTag("", XML_DBNAME);
        sr.startTag("", XML_TABLES);

        // iterate through tables
        String sTableName = "";
        String sTableSql = "";
        while (tblcur.moveToNext()) {
            sTableName = tblcur.getString(tblcur.getColumnIndex("name"));
            sTableSql = tblcur.getString(tblcur.getColumnIndex("sql"));
            if (GOLOG)
                Log.d(LOGTAG, "TABLE NAME : " + sTableName);
            // skip metadata, sequence, and uidx before exporting tables
            if (!sTableName.equals("android_metadata") && !sTableName.equals("sqlite_sequence")
                    && !sTableName.startsWith("uidx") && !sTableName.startsWith("idx_")
                    && !sTableName.startsWith("_idx")) {

                // table query and cursor
                iTableNum++;
                rowquery = "select * from " + sTableName;
                rowcur = mDB.rawQuery(rowquery, null);
                // exporting table
                sr.startTag("", XML_TABLE);
                sr.startTag("", XML_TABLENAME);
                sr.text(sTableName);
                sr.endTag("", XML_TABLENAME);
                if ((sTableSql != null) && (!sTableSql.isEmpty())) {
                    sr.startTag("", XML_TABLESQL);
                    sr.text(sTableSql);
                    sr.endTag("", XML_TABLESQL);
                }
                // iteratew through rows
                int i = -1;
                while (rowcur.moveToNext()) {
                    // at first element store column names
                    if (i == -1) {
                        sr.startTag("", XML_COLSNAME);
                        for (i = 0; i < rowcur.getColumnCount(); i++) {
                            sr.startTag("", XML_COL);
                            sr.text(rowcur.getColumnName(i));
                            sr.endTag("", XML_COL);
                        }
                        sr.endTag("", XML_COLSNAME);
                        sr.startTag("", XML_ROWS);
                    }
                    // get values
                    sr.startTag("", XML_ROW);
                    for (i = 0; i < rowcur.getColumnCount(); i++) {
                        sr.startTag("", XML_COL);
                        sr.text(rowcur.getString(i));
                        sr.endTag("", XML_COL);
                    }
                    sr.endTag("", XML_ROW);
                }
                // finishing table query
                rowcur.close();
                sr.endTag("", XML_ROWS);
                sr.endTag("", XML_TABLE);

            }
        }
        // finishing table query
        tblcur.close();
        sr.endTag("", XML_TABLES);
        sr.endTag("", XML_DATABASE);

        // finishing
        sr.endDocument();
        sr.flush();

    } catch (Exception e) {
        Log.e(LOGTAG, "error in db2xml", e);
    }

    return iTableNum;
}

From source file:org.opendatakit.services.forms.provider.FormsProvider.java

@Override
public synchronized int update(@NonNull Uri uri, ContentValues values, String where, String[] whereArgs) {
    possiblyWaitForContentProviderDebugger();

    List<String> segments = uri.getPathSegments();

    PatchedFilter pf = extractUriFeatures(uri, segments, where, whereArgs);
    WebLoggerIf logger = WebLogger.getLogger(pf.appName);

    /*/*from  w  w w  . j ava 2s. c o m*/
     * First, find out what records match this query. Replicate the 
     * ContentValues if there are multiple tableIds/formIds involved
     * and the contentValues do not have formId and tableId specified.
     * 
     * Otherwise, it is an error to specify the tableId or formId in
     * the ContentValues and have those not match the where results.
     * 
     */
    String contentTableId = (values != null && values.containsKey(FormsColumns.TABLE_ID))
            ? values.getAsString(FormsColumns.TABLE_ID)
            : null;
    String contentFormId = (values != null && values.containsKey(FormsColumns.FORM_ID))
            ? values.getAsString(FormsColumns.FORM_ID)
            : null;

    HashMap<FormSpec, HashMap<String, Object>> matchedValues = new HashMap<FormSpec, HashMap<String, Object>>();

    DbHandle dbHandleName = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .generateInternalUseDbHandle();
    OdkConnectionInterface db = null;
    try {
        // +1 referenceCount if db is returned (non-null)
        db = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().getConnection(pf.appName,
                dbHandleName);
        db.beginTransactionNonExclusive();
        Cursor c = null;
        try {
            c = db.query(DatabaseConstants.FORMS_TABLE_NAME, null, pf.whereId, pf.whereIdArgs, null, null, null,
                    null);

            if (c == null) {
                throw new SQLException(
                        "FAILED Update of " + uri + " -- query for existing row did not return a cursor");
            }
            if (c.moveToFirst()) {
                int idxId = c.getColumnIndex(FormsColumns._ID);
                int idxTableId = c.getColumnIndex(FormsColumns.TABLE_ID);
                int idxFormId = c.getColumnIndex(FormsColumns.FORM_ID);

                Integer idValue = null;
                String tableIdValue = null;
                String formIdValue = null;

                do {
                    idValue = CursorUtils.getIndexAsType(c, Integer.class, idxId);
                    tableIdValue = CursorUtils.getIndexAsString(c, idxTableId);
                    formIdValue = CursorUtils.getIndexAsString(c, idxFormId);

                    if (contentTableId != null && !contentTableId.equals(tableIdValue)) {
                        throw new SQLException("Modification of tableId for an existing form is prohibited");
                    }
                    if (contentFormId != null && !contentFormId.equals(formIdValue)) {
                        throw new SQLException("Modification of formId for an existing form is prohibited");
                    }

                    HashMap<String, Object> cv = new HashMap<String, Object>();
                    if (values != null) {
                        for (String key : values.keySet()) {
                            cv.put(key, values.get(key));
                        }
                    }
                    cv.put(FormsColumns.TABLE_ID, tableIdValue);
                    cv.put(FormsColumns.FORM_ID, formIdValue);
                    for (int idx = 0; idx < c.getColumnCount(); ++idx) {
                        String colName = c.getColumnName(idx);
                        if (colName.equals(FormsColumns._ID)) {
                            // don't insert the PK
                            continue;
                        }

                        if (c.isNull(idx)) {
                            cv.put(colName, null);
                        } else {
                            // everything else, we control...
                            Class<?> dataType = CursorUtils.getIndexDataType(c, idx);
                            if (dataType == String.class) {
                                cv.put(colName, CursorUtils.getIndexAsString(c, idx));
                            } else if (dataType == Long.class) {
                                cv.put(colName, CursorUtils.getIndexAsType(c, Long.class, idx));
                            } else if (dataType == Double.class) {
                                cv.put(colName, CursorUtils.getIndexAsType(c, Double.class, idx));
                            }
                        }
                    }

                    FormSpec formSpec = patchUpValues(pf.appName, cv);
                    formSpec._id = idValue.toString();
                    formSpec.success = false;
                    matchedValues.put(formSpec, cv);

                } while (c.moveToNext());
            } else {
                // no match on where clause...
                return 0;
            }
        } finally {
            if (c != null && !c.isClosed()) {
                c.close();
            }
        }

        // go through the entries and update the database with these patched-up values...

        for (Entry<FormSpec, HashMap<String, Object>> e : matchedValues.entrySet()) {
            FormSpec fs = e.getKey();
            HashMap<String, Object> cv = e.getValue();

            if (db.update(DatabaseConstants.FORMS_TABLE_NAME, cv, FormsColumns._ID + "=?",
                    new String[] { fs._id }) > 0) {
                fs.success = true;
            }
        }
        db.setTransactionSuccessful();

    } catch (Exception e) {
        logger.w(t, "FAILED Update of " + uri + " -- query for existing row failed: " + e.toString());

        if (e instanceof SQLException) {
            throw (SQLException) e;
        } else {
            throw new SQLException(
                    "FAILED Update of " + uri + " -- query for existing row failed: " + e.toString());
        }
    } finally {
        if (db != null) {
            try {
                if (db.inTransaction()) {
                    db.endTransaction();
                }
            } finally {
                try {
                    db.releaseReference();
                } finally {
                    // this closes the connection
                    OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
                            .removeConnection(pf.appName, dbHandleName);
                }
            }
        }
    }

    int failureCount = 0;
    for (FormSpec fs : matchedValues.keySet()) {
        if (fs.success) {
            Uri formUri = Uri
                    .withAppendedPath(
                            Uri.withAppendedPath(Uri.withAppendedPath(
                                    Uri.parse("content://" + getFormsAuthority()), pf.appName), fs.tableId),
                            fs.formId);
            getContext().getContentResolver().notifyChange(formUri, null);
            Uri idUri = Uri.withAppendedPath(
                    Uri.withAppendedPath(Uri.parse("content://" + getFormsAuthority()), pf.appName), fs._id);
            getContext().getContentResolver().notifyChange(idUri, null);
        } else {
            ++failureCount;
        }
    }
    getContext().getContentResolver().notifyChange(uri, null);

    int count = matchedValues.size();
    if (failureCount != 0) {
        throw new SQLiteException(
                "Unable to update all forms (" + (count - failureCount) + " of " + count + " updated)");
    }
    return count;
}

From source file:it.bradipao.berengar.DbTool.java

public static int db2gson(SQLiteDatabase mDB, File jsonFile) {
    // vars//from w  w w  . j  a v a2  s .c om
    int iTableNum = 0;
    FileWriter fw = null;
    BufferedWriter bw = null;
    JsonWriter jw = null;
    String sqlquery = "";
    Cursor cur = null;

    String mTable = null;
    String mTableSql = null;
    ArrayList<String> aTable = new ArrayList<String>();
    ArrayList<String> aTableSql = new ArrayList<String>();

    // file writers
    try {
        fw = new FileWriter(jsonFile);
        bw = new BufferedWriter(fw);
        jw = new JsonWriter(bw);
    } catch (FileNotFoundException e) {
        Log.e(LOGTAG, "error in db2gson file writers", e);
    } catch (IOException e) {
        Log.e(LOGTAG, "error in db2gson file writers", e);
    }

    // read tables list and extract name and createsql
    sqlquery = "select * from sqlite_master";
    cur = mDB.rawQuery(sqlquery, null);
    while (cur.moveToNext()) {
        mTable = cur.getString(cur.getColumnIndex("name"));
        mTableSql = cur.getString(cur.getColumnIndex("sql"));
        // add new table, and skip metadata, sequence, and uidx before exporting tables
        if (!mTable.equals("android_metadata") && !mTable.equals("sqlite_sequence")
                && !mTable.startsWith("uidx") && !mTable.startsWith("idx_") && !mTable.startsWith("_idx")) {
            iTableNum++;
            aTable.add(mTable);
            aTableSql.add(mTableSql);
            if (GOLOG)
                Log.d(LOGTAG, "TABLE NAME : " + mTable);
        }
    }
    cur.close();

    // start writing json
    try {
        // open root {
        jw.beginObject();
        // header elements
        jw.name("tables_num").value(Integer.toString(iTableNum));
        jw.name("jsondb_format").value("1");
        // tables name
        jw.name("tables_name");
        jw.beginArray();
        for (int i = 0; i < aTable.size(); i++)
            jw.value(aTable.get(i));
        jw.endArray();

        // open tables array
        jw.name("tables");
        jw.beginArray();
        // iterate through tables
        for (int i = 0; i < aTable.size(); i++) {
            // open table object
            jw.beginObject();
            // table name and table sql
            jw.name("table_name").value(aTable.get(i));
            jw.name("table_sql").value(aTableSql.get(i));
            // iteratew through rows
            sqlquery = "select * from " + aTable.get(i);
            cur = mDB.rawQuery(sqlquery, null);
            int k = -1;
            while (cur.moveToNext()) {
                if (k == -1) {
                    // column names generated at very first row
                    jw.name("cols_name");
                    jw.beginArray();
                    for (k = 0; k < cur.getColumnCount(); k++)
                        jw.value(cur.getColumnName(k));
                    jw.endArray();
                    // open rows array
                    jw.name("rows");
                    jw.beginArray();
                }
                // get columns values in row
                jw.beginArray();
                for (k = 0; k < cur.getColumnCount(); k++)
                    jw.value(cur.getString(k));
                jw.endArray();
            }
            // close rows array
            jw.endArray();
            // close table object
            jw.endObject();
        }
        // close tables array
        jw.endArray();

        // close root {
        jw.endObject();
        jw.close();
    } catch (IOException e) {
        Log.e(LOGTAG, "error in db2gson file writers", e);
    }

    // return number of tables
    return iTableNum;
}

From source file:org.opendatakit.services.database.utlities.ODKDatabaseImplUtils.java

private BaseTable buildBaseTable(OdkConnectionInterface db, Cursor c, String tableId, boolean canCreateRow) {

    HashMap<String, Integer> mElementKeyToIndex = null;
    String[] mElementKeyForIndex = null;

    if (!c.moveToFirst()) {

        // Attempt to retrieve the columns from the cursor.
        // These may not be available if there were no rows returned.
        // It depends upon the cursor implementation.
        try {//  w  ww.j a  va2s . com
            int columnCount = c.getColumnCount();
            mElementKeyForIndex = new String[columnCount];
            mElementKeyToIndex = new HashMap<>(columnCount);
            int i;

            for (i = 0; i < columnCount; ++i) {
                String columnName = c.getColumnName(i);
                mElementKeyForIndex[i] = columnName;
                mElementKeyToIndex.put(columnName, i);
            }
        } catch (Exception e) {
            // ignore.
        }

        // if they were not available, declare an empty array.
        if (mElementKeyForIndex == null) {
            mElementKeyForIndex = new String[0];
        }
        c.close();

        // we have no idea what the table should contain because it has no rows...
        BaseTable table = new BaseTable(null, mElementKeyForIndex, mElementKeyToIndex, 0);
        table.setEffectiveAccessCreateRow(canCreateRow);
        return table;
    }

    int rowCount = c.getCount();
    int columnCount = c.getColumnCount();

    BaseTable table = null;

    // These maps will map the element key to the corresponding index in
    // either data or metadata. If the user has defined a column with the
    // element key _my_data, and this column is at index 5 in the data
    // array, dataKeyToIndex would then have a mapping of _my_data:5.
    // The sync_state column, if present at index 7, would have a mapping
    // in metadataKeyToIndex of sync_state:7.
    mElementKeyForIndex = new String[columnCount];
    mElementKeyToIndex = new HashMap<>(columnCount);

    int i;

    for (i = 0; i < columnCount; ++i) {
        String columnName = c.getColumnName(i);
        mElementKeyForIndex[i] = columnName;
        mElementKeyToIndex.put(columnName, i);
    }

    table = new BaseTable(null, mElementKeyForIndex, mElementKeyToIndex, rowCount);

    String[] rowData = new String[columnCount];
    do {
        // First get the user-defined data for this row.
        for (i = 0; i < columnCount; i++) {
            String value = CursorUtils.getIndexAsString(c, i);
            rowData[i] = value;
        }

        Row nextRow = new Row(rowData.clone(), table);
        table.addRow(nextRow);
    } while (c.moveToNext());
    c.close();

    table.setEffectiveAccessCreateRow(canCreateRow);

    if (tableId != null) {
        table.setMetaDataRev(getTableDefinitionRevId(db, tableId));
    }
    return table;
}

From source file:org.opendatakit.survey.android.provider.SubmissionProvider.java

/**
 * The incoming URI is of the form:/*from w w  w.jav a 2  s .  c  o m*/
 * ..../appName/tableId/instanceId?formId=&formVersion=
 *
 * where instanceId is the DataTableColumns._ID
 */
@SuppressWarnings("unchecked")
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    final boolean asXml = uri.getAuthority().equalsIgnoreCase(XML_SUBMISSION_AUTHORITY);

    if (mode != null && !mode.equals("r")) {
        throw new IllegalArgumentException("Only read access is supported");
    }

    // URI == ..../appName/tableId/instanceId?formId=&formVersion=

    List<String> segments = uri.getPathSegments();

    if (segments.size() != 4) {
        throw new IllegalArgumentException("Unknown URI (incorrect number of path segments!) " + uri);
    }

    final String appName = segments.get(0);
    ODKFileUtils.verifyExternalStorageAvailability();
    ODKFileUtils.assertDirectoryStructure(appName);
    WebLogger log = WebLogger.getLogger(appName);

    final String tableId = segments.get(1);
    final String instanceId = segments.get(2);
    final String submissionInstanceId = segments.get(3);

    SQLiteDatabase db = null;
    try {
        db = DatabaseFactory.get().getDatabase(getContext(), appName);

        boolean success = false;
        try {
            success = ODKDatabaseUtils.get().hasTableId(db, tableId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SQLException("Unknown URI (exception testing for tableId) " + uri);
        }
        if (!success) {
            throw new SQLException("Unknown URI (missing data table for tableId) " + uri);
        }

        final String dbTableName = "\"" + tableId + "\"";

        // Get the table properties specific to XML submissions

        String xmlInstanceName = null;
        String xmlRootElementName = null;
        String xmlDeviceIdPropertyName = null;
        String xmlUserIdPropertyName = null;
        String xmlBase64RsaPublicKey = null;

        try {

            Cursor c = null;
            try {
                c = db.query(DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME,
                        new String[] { KeyValueStoreColumns.KEY, KeyValueStoreColumns.VALUE },
                        KeyValueStoreColumns.TABLE_ID + "=? AND " + KeyValueStoreColumns.PARTITION + "=? AND "
                                + KeyValueStoreColumns.ASPECT + "=? AND " + KeyValueStoreColumns.KEY
                                + " IN (?,?,?,?,?)",
                        new String[] { tableId, KeyValueStoreConstants.PARTITION_TABLE,
                                KeyValueStoreConstants.ASPECT_DEFAULT, KeyValueStoreConstants.XML_INSTANCE_NAME,
                                KeyValueStoreConstants.XML_ROOT_ELEMENT_NAME,
                                KeyValueStoreConstants.XML_DEVICE_ID_PROPERTY_NAME,
                                KeyValueStoreConstants.XML_USER_ID_PROPERTY_NAME,
                                KeyValueStoreConstants.XML_BASE64_RSA_PUBLIC_KEY },
                        null, null, null);
                if (c.getCount() > 0) {
                    c.moveToFirst();
                    int idxKey = c.getColumnIndex(KeyValueStoreColumns.KEY);
                    int idxValue = c.getColumnIndex(KeyValueStoreColumns.VALUE);
                    do {
                        String key = c.getString(idxKey);
                        String value = c.getString(idxValue);
                        if (KeyValueStoreConstants.XML_INSTANCE_NAME.equals(key)) {
                            xmlInstanceName = value;
                        } else if (KeyValueStoreConstants.XML_ROOT_ELEMENT_NAME.equals(key)) {
                            xmlRootElementName = value;
                        } else if (KeyValueStoreConstants.XML_DEVICE_ID_PROPERTY_NAME.equals(key)) {
                            xmlDeviceIdPropertyName = value;
                        } else if (KeyValueStoreConstants.XML_USER_ID_PROPERTY_NAME.equals(key)) {
                            xmlUserIdPropertyName = value;
                        } else if (KeyValueStoreConstants.XML_BASE64_RSA_PUBLIC_KEY.equals(key)) {
                            xmlBase64RsaPublicKey = value;
                        }
                    } while (c.moveToNext());
                }
            } finally {
                c.close();
                c = null;
            }

            ArrayList<ColumnDefinition> orderedDefns = TableUtil.get().getColumnDefinitions(db, appName,
                    tableId);

            // Retrieve the values of the record to be emitted...

            HashMap<String, Object> values = new HashMap<String, Object>();

            // issue query to retrieve the most recent non-checkpoint data record
            // for the instanceId
            StringBuilder b = new StringBuilder();
            b.append("SELECT * FROM ").append(dbTableName).append(" as T WHERE ").append(DataTableColumns.ID)
                    .append("=?").append(" AND ").append(DataTableColumns.SAVEPOINT_TYPE)
                    .append(" IS NOT NULL AND ").append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                    .append("=(SELECT max(V.").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                    .append(dbTableName).append(" as V WHERE V.").append(DataTableColumns.ID).append("=T.")
                    .append(DataTableColumns.ID).append(" AND V.").append(DataTableColumns.SAVEPOINT_TYPE)
                    .append(" IS NOT NULL").append(")");

            String[] selectionArgs = new String[] { instanceId };
            FileSet freturn = new FileSet(appName);

            String datestamp = null;

            try {
                c = db.rawQuery(b.toString(), selectionArgs);
                b.setLength(0);

                if (c.moveToFirst() && c.getCount() == 1) {
                    String rowETag = null;
                    String filterType = null;
                    String filterValue = null;
                    String formId = null;
                    String locale = null;
                    String savepointType = null;
                    String savepointCreator = null;
                    String savepointTimestamp = null;
                    String instanceName = null;

                    // OK. we have the record -- work through all the terms
                    for (int i = 0; i < c.getColumnCount(); ++i) {
                        ColumnDefinition defn = null;
                        String columnName = c.getColumnName(i);
                        try {
                            defn = ColumnDefinition.find(orderedDefns, columnName);
                        } catch (IllegalArgumentException e) {
                            // ignore...
                        }
                        if (defn != null && !c.isNull(i)) {
                            if (xmlInstanceName != null && defn.getElementName().equals(xmlInstanceName)) {
                                instanceName = ODKDatabaseUtils.get().getIndexAsString(c, i);
                            }
                            // user-defined column
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();

                            log.i(t, "element type: " + defn.getElementType());
                            if (dataType == ElementDataType.integer) {
                                Integer value = ODKDatabaseUtils.get().getIndexAsType(c, Integer.class, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.number) {
                                Double value = ODKDatabaseUtils.get().getIndexAsType(c, Double.class, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.bool) {
                                Integer tmp = ODKDatabaseUtils.get().getIndexAsType(c, Integer.class, i);
                                Boolean value = tmp == null ? null : (tmp != 0);
                                putElementValue(values, defn, value);
                            } else if (type.getElementType().equals("date")) {
                                String value = ODKDatabaseUtils.get().getIndexAsString(c, i);
                                String jrDatestamp = (value == null) ? null
                                        : (new SimpleDateFormat(ISO8601_DATE_ONLY_FORMAT, Locale.ENGLISH))
                                                .format(new Date(TableConstants.milliSecondsFromNanos(value)));
                                putElementValue(values, defn, jrDatestamp);
                            } else if (type.getElementType().equals("dateTime")) {
                                String value = ODKDatabaseUtils.get().getIndexAsString(c, i);
                                String jrDatestamp = (value == null) ? null
                                        : (new SimpleDateFormat(ISO8601_DATE_FORMAT, Locale.ENGLISH))
                                                .format(new Date(TableConstants.milliSecondsFromNanos(value)));
                                putElementValue(values, defn, jrDatestamp);
                            } else if (type.getElementType().equals("time")) {
                                String value = ODKDatabaseUtils.get().getIndexAsString(c, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.array) {
                                ArrayList<Object> al = ODKDatabaseUtils.get().getIndexAsType(c, ArrayList.class,
                                        i);
                                putElementValue(values, defn, al);
                            } else if (dataType == ElementDataType.string) {
                                String value = ODKDatabaseUtils.get().getIndexAsString(c, i);
                                putElementValue(values, defn, value);
                            } else /* unrecognized */ {
                                throw new IllegalStateException(
                                        "unrecognized data type: " + defn.getElementType());
                            }

                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                            savepointTimestamp = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.ROW_ETAG)) {
                            rowETag = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FILTER_TYPE)) {
                            filterType = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FILTER_VALUE)) {
                            filterValue = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FORM_ID)) {
                            formId = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.LOCALE)) {
                            locale = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FORM_ID)) {
                            formId = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                            savepointType = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_CREATOR)) {
                            savepointCreator = ODKDatabaseUtils.get().getIndexAsString(c, i);
                        }
                    }

                    // OK got all the values into the values map -- emit
                    // contents
                    b.setLength(0);
                    File submissionXml = new File(ODKFileUtils.getInstanceFolder(appName, tableId, instanceId),
                            (asXml ? "submission.xml" : "submission.json"));
                    File manifest = new File(ODKFileUtils.getInstanceFolder(appName, tableId, instanceId),
                            "manifest.json");
                    submissionXml.delete();
                    manifest.delete();
                    freturn.instanceFile = submissionXml;

                    if (asXml) {
                        // Pre-processing -- collapse all geopoints into a
                        // string-valued representation
                        for (ColumnDefinition defn : orderedDefns) {
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();
                            if (dataType == ElementDataType.object && (type.getElementType().equals("geopoint")
                                    || type.getElementType().equals("mimeUri"))) {
                                Map<String, Object> parent = null;
                                List<ColumnDefinition> parents = new ArrayList<ColumnDefinition>();
                                ColumnDefinition d = defn.getParent();
                                while (d != null) {
                                    parents.add(d);
                                    d = d.getParent();
                                }
                                parent = values;
                                for (int i = parents.size() - 1; i >= 0; --i) {
                                    Object o = parent.get(parents.get(i).getElementName());
                                    if (o == null) {
                                        parent = null;
                                        break;
                                    }
                                    parent = (Map<String, Object>) o;
                                }
                                if (parent != null) {
                                    Object o = parent.get(defn.getElementName());
                                    if (o != null) {
                                        if (type.getElementType().equals("geopoint")) {
                                            Map<String, Object> geopoint = (Map<String, Object>) o;
                                            // OK. we have geopoint -- get the
                                            // lat, long, alt, etc.
                                            Double latitude = (Double) geopoint.get("latitude");
                                            Double longitude = (Double) geopoint.get("longitude");
                                            Double altitude = (Double) geopoint.get("altitude");
                                            Double accuracy = (Double) geopoint.get("accuracy");
                                            String gpt = "" + latitude + " " + longitude + " " + altitude + " "
                                                    + accuracy;
                                            parent.put(defn.getElementName(), gpt);
                                        } else if (type.getElementType().equals("mimeUri")) {
                                            Map<String, Object> mimeuri = (Map<String, Object>) o;
                                            String uriFragment = (String) mimeuri.get("uriFragment");
                                            String contentType = (String) mimeuri.get("contentType");

                                            if (uriFragment != null) {
                                                File f = ODKFileUtils.getAsFile(appName, uriFragment);
                                                if (f.equals(manifest)) {
                                                    throw new IllegalStateException(
                                                            "Unexpected collision with manifest.json");
                                                }
                                                freturn.addAttachmentFile(f, contentType);
                                                parent.put(defn.getElementName(), f.getName());
                                            }
                                        } else {
                                            throw new IllegalStateException("Unhandled transform case");
                                        }
                                    }
                                }
                            }
                        }

                        datestamp = (new SimpleDateFormat(ISO8601_DATE_FORMAT, Locale.ENGLISH))
                                .format(new Date(TableConstants.milliSecondsFromNanos(savepointTimestamp)));

                        // For XML, we traverse the map to serialize it
                        Document d = new Document();
                        d.setStandalone(true);
                        d.setEncoding(CharEncoding.UTF_8);
                        Element e = d.createElement(XML_DEFAULT_NAMESPACE,
                                (xmlRootElementName == null) ? "data" : xmlRootElementName);
                        e.setPrefix("jr", XML_OPENROSA_NAMESPACE);
                        e.setPrefix("", XML_DEFAULT_NAMESPACE);
                        d.addChild(0, Node.ELEMENT, e);
                        e.setAttribute("", "id", tableId);
                        DynamicPropertiesCallback cb = new DynamicPropertiesCallback(getContext(), appName,
                                tableId, instanceId);

                        int idx = 0;
                        Element meta = d.createElement(XML_OPENROSA_NAMESPACE, "meta");

                        Element v = d.createElement(XML_OPENROSA_NAMESPACE, "instanceID");
                        v.addChild(0, Node.TEXT, submissionInstanceId);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        if (xmlDeviceIdPropertyName != null) {
                            String deviceId = propertyManager.getSingularProperty(xmlDeviceIdPropertyName, cb);
                            if (deviceId != null) {
                                v = d.createElement(XML_OPENROSA_NAMESPACE, "deviceID");
                                v.addChild(0, Node.TEXT, deviceId);
                                meta.addChild(idx++, Node.ELEMENT, v);
                                meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);
                            }
                        }
                        if (xmlUserIdPropertyName != null) {
                            String userId = propertyManager.getSingularProperty(xmlUserIdPropertyName, cb);
                            if (userId != null) {
                                v = d.createElement(XML_OPENROSA_NAMESPACE, "userID");
                                v.addChild(0, Node.TEXT, userId);
                                meta.addChild(idx++, Node.ELEMENT, v);
                                meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);
                            }
                        }
                        v = d.createElement(XML_OPENROSA_NAMESPACE, "timeEnd");
                        v.addChild(0, Node.TEXT, datestamp);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // these are extra metadata tags...
                        if (instanceName != null) {
                            v = d.createElement(XML_DEFAULT_NAMESPACE, "instanceName");
                            v.addChild(0, Node.TEXT, instanceName);
                            meta.addChild(idx++, Node.ELEMENT, v);
                            meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);
                        } else {
                            v = d.createElement(XML_DEFAULT_NAMESPACE, "instanceName");
                            v.addChild(0, Node.TEXT, savepointTimestamp);
                            meta.addChild(idx++, Node.ELEMENT, v);
                            meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);
                        }

                        // these are extra metadata tags...
                        // rowID
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "rowID");
                        v.addChild(0, Node.TEXT, instanceId);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // rowETag
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "rowETag");
                        if (rowETag != null) {
                            v.addChild(0, Node.TEXT, rowETag);
                        }
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // filterType
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "filterType");
                        if (filterType != null) {
                            v.addChild(0, Node.TEXT, filterType);
                        }
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // filterValue
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "filterValue");
                        if (filterValue != null) {
                            v.addChild(0, Node.TEXT, filterValue);
                        }
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // formID
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "formID");
                        v.addChild(0, Node.TEXT, formId);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // locale
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "locale");
                        v.addChild(0, Node.TEXT, locale);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // savepointType
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "savepointType");
                        v.addChild(0, Node.TEXT, savepointType);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // savepointCreator
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "savepointCreator");
                        if (savepointCreator != null) {
                            v.addChild(0, Node.TEXT, savepointCreator);
                        }
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // savepointTimestamp
                        v = d.createElement(XML_DEFAULT_NAMESPACE, "savepointTimestamp");
                        v.addChild(0, Node.TEXT, savepointTimestamp);
                        meta.addChild(idx++, Node.ELEMENT, v);
                        meta.addChild(idx++, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        // and insert the meta block into the XML

                        e.addChild(0, Node.IGNORABLE_WHITESPACE, NEW_LINE);
                        e.addChild(1, Node.ELEMENT, meta);
                        e.addChild(2, Node.IGNORABLE_WHITESPACE, NEW_LINE);

                        idx = 3;
                        ArrayList<String> entryNames = new ArrayList<String>();
                        entryNames.addAll(values.keySet());
                        Collections.sort(entryNames);
                        for (String name : entryNames) {
                            idx = generateXmlHelper(d, e, idx, name, values, log);
                        }

                        KXmlSerializer serializer = new KXmlSerializer();

                        ByteArrayOutputStream bo = new ByteArrayOutputStream();
                        serializer.setOutput(bo, CharEncoding.UTF_8);
                        // setting the response content type emits the
                        // xml header.
                        // just write the body here...
                        d.writeChildren(serializer);
                        serializer.flush();
                        bo.close();

                        b.append(bo.toString(CharEncoding.UTF_8));

                        // OK we have the document in the builder (b).
                        String doc = b.toString();

                        freturn.instanceFile = submissionXml;

                        // see if the form is encrypted and we can
                        // encrypt it...
                        EncryptedFormInformation formInfo = EncryptionUtils.getEncryptedFormInformation(appName,
                                tableId, xmlBase64RsaPublicKey, instanceId);
                        if (formInfo != null) {
                            File submissionXmlEnc = new File(submissionXml.getParentFile(),
                                    submissionXml.getName() + ".enc");
                            submissionXmlEnc.delete();
                            // if we are encrypting, the form cannot be
                            // reopened afterward
                            // and encrypt the submission (this is a
                            // one-way operation)...
                            if (!EncryptionUtils.generateEncryptedSubmission(freturn, doc, submissionXml,
                                    submissionXmlEnc, formInfo)) {
                                return null;
                            }
                            // at this point, the freturn object has
                            // been re-written with the encrypted media
                            // and xml files.
                        } else {
                            exportFile(doc, submissionXml, log);
                        }

                    } else {
                        // Pre-processing -- collapse all mimeUri into filename
                        for (ColumnDefinition defn : orderedDefns) {
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();

                            if (dataType == ElementDataType.object && type.getElementType().equals("mimeUri")) {
                                Map<String, Object> parent = null;
                                List<ColumnDefinition> parents = new ArrayList<ColumnDefinition>();
                                ColumnDefinition d = defn.getParent();
                                while (d != null) {
                                    parents.add(d);
                                    d = d.getParent();
                                }
                                parent = values;
                                for (int i = parents.size() - 1; i >= 0; --i) {
                                    Object o = parent.get(parents.get(i).getElementName());
                                    if (o == null) {
                                        parent = null;
                                        break;
                                    }
                                    parent = (Map<String, Object>) o;
                                }
                                if (parent != null) {
                                    Object o = parent.get(defn.getElementName());
                                    if (o != null) {
                                        if (dataType == ElementDataType.object
                                                && type.getElementType().equals("mimeUri")) {
                                            Map<String, Object> mimeuri = (Map<String, Object>) o;
                                            String uriFragment = (String) mimeuri.get("uriFragment");
                                            String contentType = (String) mimeuri.get("contentType");
                                            File f = ODKFileUtils.getAsFile(appName, uriFragment);
                                            if (f.equals(manifest)) {
                                                throw new IllegalStateException(
                                                        "Unexpected collision with manifest.json");
                                            }
                                            freturn.addAttachmentFile(f, contentType);
                                            parent.put(defn.getElementName(), f.getName());
                                        } else {
                                            throw new IllegalStateException("Unhandled transform case");
                                        }
                                    }
                                }
                            }
                        }

                        // For JSON, we construct the model, then emit model +
                        // meta + data
                        HashMap<String, Object> wrapper = new HashMap<String, Object>();
                        wrapper.put("tableId", tableId);
                        wrapper.put("instanceId", instanceId);
                        HashMap<String, Object> formDef = new HashMap<String, Object>();
                        formDef.put("table_id", tableId);
                        formDef.put("model", ColumnDefinition.getDataModel(orderedDefns));
                        wrapper.put("formDef", formDef);
                        wrapper.put("data", values);
                        wrapper.put("metadata", new HashMap<String, Object>());
                        HashMap<String, Object> elem = (HashMap<String, Object>) wrapper.get("metadata");
                        if (instanceName != null) {
                            elem.put("instanceName", instanceName);
                        }
                        elem.put("saved", "COMPLETE");
                        elem.put("timestamp", datestamp);

                        b.append(ODKFileUtils.mapper.writeValueAsString(wrapper));

                        // OK we have the document in the builder (b).
                        String doc = b.toString();
                        exportFile(doc, submissionXml, log);
                    }
                    exportFile(freturn.serializeUriFragmentList(getContext()), manifest, log);
                    return ParcelFileDescriptor.open(manifest, ParcelFileDescriptor.MODE_READ_ONLY);

                }
            } finally {
                if (c != null && !c.isClosed()) {
                    c.close();
                }
            }

        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    } finally {
        if (db != null) {
            db.close();
        }
    }
    return null;
}

From source file:org.opendatakit.services.submissions.provider.SubmissionProvider.java

/**
 * The incoming URI is of the form://from   w w w  . jav a 2 s  .c  om
 * ..../appName/tableId/instanceId?formId=&formVersion=
 *
 * where instanceId is the DataTableColumns._ID
 */
@SuppressWarnings("unchecked")
@Override
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {

    possiblyWaitForContentProviderDebugger();

    final boolean asXml = uri.getAuthority().equalsIgnoreCase(ProviderConsts.XML_SUBMISSION_AUTHORITY);

    if (mode != null && !mode.equals("r")) {
        throw new IllegalArgumentException("Only read access is supported");
    }

    // URI == ..../appName/tableId/instanceId?formId=&formVersion=

    List<String> segments = uri.getPathSegments();

    if (segments.size() != 4) {
        throw new IllegalArgumentException("Unknown URI (incorrect number of path segments!) " + uri);
    }

    PropertyManager propertyManager = new PropertyManager(getContext());

    final String appName = segments.get(0);
    ODKFileUtils.verifyExternalStorageAvailability();
    ODKFileUtils.assertDirectoryStructure(appName);
    WebLoggerIf logger = WebLogger.getLogger(appName);

    final String tableId = segments.get(1);
    final String instanceId = segments.get(2);
    final String submissionInstanceId = segments.get(3);

    PropertiesSingleton props = CommonToolProperties.get(getContext(), appName);
    String userEmail = props.getProperty(CommonToolProperties.KEY_ACCOUNT);
    String username = props.getProperty(CommonToolProperties.KEY_USERNAME);
    String activeUser = props.getActiveUser();
    String rolesList = props.getProperty(CommonToolProperties.KEY_ROLES_LIST);
    String currentLocale = props.getLocale();

    DbHandle dbHandleName = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .generateInternalUseDbHandle();
    OdkConnectionInterface db = null;
    try {
        // +1 referenceCount if db is returned (non-null)
        db = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().getConnection(appName,
                dbHandleName);

        boolean success = false;
        try {
            success = ODKDatabaseImplUtils.get().hasTableId(db, tableId);
        } catch (Exception e) {
            logger.printStackTrace(e);
            throw new SQLException("Unknown URI (exception testing for tableId) " + uri);
        }
        if (!success) {
            throw new SQLException("Unknown URI (missing data table for tableId) " + uri);
        }

        // Get the table properties specific to XML submissions

        String xmlInstanceName = null;
        String xmlRootElementName = null;
        String xmlDeviceIdPropertyName = null;
        String xmlUserIdPropertyName = null;
        String xmlBase64RsaPublicKey = null;

        try {

            Cursor c = null;
            try {
                c = db.query(DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME,
                        new String[] { KeyValueStoreColumns.KEY, KeyValueStoreColumns.VALUE },
                        KeyValueStoreColumns.TABLE_ID + "=? AND " + KeyValueStoreColumns.PARTITION + "=? AND "
                                + KeyValueStoreColumns.ASPECT + "=? AND " + KeyValueStoreColumns.KEY
                                + " IN (?,?,?,?,?)",
                        new String[] { tableId, KeyValueStoreConstants.PARTITION_TABLE,
                                KeyValueStoreConstants.ASPECT_DEFAULT, KeyValueStoreConstants.XML_INSTANCE_NAME,
                                KeyValueStoreConstants.XML_ROOT_ELEMENT_NAME,
                                KeyValueStoreConstants.XML_DEVICE_ID_PROPERTY_NAME,
                                KeyValueStoreConstants.XML_USER_ID_PROPERTY_NAME,
                                KeyValueStoreConstants.XML_BASE64_RSA_PUBLIC_KEY },
                        null, null, null, null);
                c.moveToFirst();

                if (c.getCount() > 0) {
                    int idxKey = c.getColumnIndex(KeyValueStoreColumns.KEY);
                    int idxValue = c.getColumnIndex(KeyValueStoreColumns.VALUE);
                    do {
                        String key = c.getString(idxKey);
                        String value = c.getString(idxValue);
                        if (KeyValueStoreConstants.XML_INSTANCE_NAME.equals(key)) {
                            xmlInstanceName = value;
                        } else if (KeyValueStoreConstants.XML_ROOT_ELEMENT_NAME.equals(key)) {
                            xmlRootElementName = value;
                        } else if (KeyValueStoreConstants.XML_DEVICE_ID_PROPERTY_NAME.equals(key)) {
                            xmlDeviceIdPropertyName = value;
                        } else if (KeyValueStoreConstants.XML_USER_ID_PROPERTY_NAME.equals(key)) {
                            xmlUserIdPropertyName = value;
                        } else if (KeyValueStoreConstants.XML_BASE64_RSA_PUBLIC_KEY.equals(key)) {
                            xmlBase64RsaPublicKey = value;
                        }
                    } while (c.moveToNext());
                }
            } finally {
                c.close();
                c = null;
            }

            OrderedColumns orderedDefns = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId);

            // Retrieve the values of the record to be emitted...

            HashMap<String, Object> values = new HashMap<String, Object>();

            // issue query to retrieve the most recent non-checkpoint data record
            // for the instanceId
            StringBuilder b = new StringBuilder();
            b.append("SELECT * FROM ").append(tableId).append(" as T WHERE ").append(DataTableColumns.ID)
                    .append("=?").append(" AND ").append(DataTableColumns.SAVEPOINT_TYPE)
                    .append(" IS NOT NULL AND ").append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                    .append("=(SELECT max(V.").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                    .append(tableId).append(" as V WHERE V.").append(DataTableColumns.ID).append("=T.")
                    .append(DataTableColumns.ID).append(" AND V.").append(DataTableColumns.SAVEPOINT_TYPE)
                    .append(" IS NOT NULL").append(")");

            String[] selectionArgs = new String[] { instanceId };
            FileSet freturn = new FileSet(appName);

            String datestamp = null;

            try {

                ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get()
                        .getAccessContext(db, tableId, activeUser, rolesList);

                c = ODKDatabaseImplUtils.get().rawQuery(db, b.toString(), selectionArgs, null, accessContext);
                b.setLength(0);

                if (c.moveToFirst() && c.getCount() == 1) {
                    String rowETag = null;
                    String filterType = null;
                    String filterValue = null;
                    String formId = null;
                    String locale = null;
                    String savepointType = null;
                    String savepointCreator = null;
                    String savepointTimestamp = null;
                    String instanceName = null;

                    // OK. we have the record -- work through all the terms
                    for (int i = 0; i < c.getColumnCount(); ++i) {
                        ColumnDefinition defn = null;
                        String columnName = c.getColumnName(i);
                        try {
                            defn = orderedDefns.find(columnName);
                        } catch (IllegalArgumentException e) {
                            // ignore...
                        }
                        if (defn != null && !c.isNull(i)) {
                            if (xmlInstanceName != null && defn.getElementName().equals(xmlInstanceName)) {
                                instanceName = CursorUtils.getIndexAsString(c, i);
                            }
                            // user-defined column
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();

                            logger.i(t, "element type: " + defn.getElementType());
                            if (dataType == ElementDataType.integer) {
                                Integer value = CursorUtils.getIndexAsType(c, Integer.class, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.number) {
                                Double value = CursorUtils.getIndexAsType(c, Double.class, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.bool) {
                                Integer tmp = CursorUtils.getIndexAsType(c, Integer.class, i);
                                Boolean value = tmp == null ? null : (tmp != 0);
                                putElementValue(values, defn, value);
                            } else if (type.getElementType().equals("date")) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                String jrDatestamp = (value == null) ? null
                                        : (new SimpleDateFormat(ISO8601_DATE_ONLY_FORMAT, Locale.US))
                                                .format(new Date(TableConstants.milliSecondsFromNanos(value)));
                                putElementValue(values, defn, jrDatestamp);
                            } else if (type.getElementType().equals("dateTime")) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                String jrDatestamp = (value == null) ? null
                                        : (new SimpleDateFormat(ISO8601_DATE_FORMAT, Locale.US))
                                                .format(new Date(TableConstants.milliSecondsFromNanos(value)));
                                putElementValue(values, defn, jrDatestamp);
                            } else if (type.getElementType().equals("time")) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.array) {
                                ArrayList<Object> al = CursorUtils.getIndexAsType(c, ArrayList.class, i);
                                putElementValue(values, defn, al);
                            } else if (dataType == ElementDataType.string) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                putElementValue(values, defn, value);
                            } else /* unrecognized */ {
                                throw new IllegalStateException(
                                        "unrecognized data type: " + defn.getElementType());
                            }

                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                            savepointTimestamp = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.ROW_ETAG)) {
                            rowETag = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FILTER_TYPE)) {
                            filterType = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FILTER_VALUE)) {
                            filterValue = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FORM_ID)) {
                            formId = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.LOCALE)) {
                            locale = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FORM_ID)) {
                            formId = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                            savepointType = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_CREATOR)) {
                            savepointCreator = CursorUtils.getIndexAsString(c, i);
                        }
                    }

                    // OK got all the values into the values map -- emit
                    // contents
                    b.setLength(0);
                    File submissionXml = new File(ODKFileUtils.getInstanceFolder(appName, tableId, instanceId),
                            (asXml ? "submission.xml" : "submission.json"));
                    File manifest = new File(ODKFileUtils.getInstanceFolder(appName, tableId, instanceId),
                            "manifest.json");
                    submissionXml.delete();
                    manifest.delete();
                    freturn.instanceFile = submissionXml;

                    if (asXml) {
                        // Pre-processing -- collapse all geopoints into a
                        // string-valued representation
                        for (ColumnDefinition defn : orderedDefns.getColumnDefinitions()) {
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();
                            if (dataType == ElementDataType.object && (type.getElementType().equals("geopoint")
                                    || type.getElementType().equals("mimeUri"))) {
                                Map<String, Object> parent = null;
                                List<ColumnDefinition> parents = new ArrayList<ColumnDefinition>();
                                ColumnDefinition d = defn.getParent();
                                while (d != null) {
                                    parents.add(d);
                                    d = d.getParent();
                                }
                                parent = values;
                                for (int i = parents.size() - 1; i >= 0; --i) {
                                    Object o = parent.get(parents.get(i).getElementName());
                                    if (o == null) {
                                        parent = null;
                                        break;
                                    }
                                    parent = (Map<String, Object>) o;
                                }
                                if (parent != null) {
                                    Object o = parent.get(defn.getElementName());
                                    if (o != null) {
                                        if (type.getElementType().equals("geopoint")) {
                                            Map<String, Object> geopoint = (Map<String, Object>) o;
                                            // OK. we have geopoint -- get the
                                            // lat, long, alt, etc.
                                            Double latitude = (Double) geopoint.get("latitude");
                                            Double longitude = (Double) geopoint.get("longitude");
                                            Double altitude = (Double) geopoint.get("altitude");
                                            Double accuracy = (Double) geopoint.get("accuracy");
                                            String gpt = "" + latitude + " " + longitude + " " + altitude + " "
                                                    + accuracy;
                                            parent.put(defn.getElementName(), gpt);
                                        } else if (type.getElementType().equals("mimeUri")) {
                                            Map<String, Object> mimeuri = (Map<String, Object>) o;
                                            String uriFragment = (String) mimeuri.get("uriFragment");
                                            String contentType = (String) mimeuri.get("contentType");

                                            if (uriFragment != null) {
                                                File f = ODKFileUtils.getAsFile(appName, uriFragment);
                                                if (f.equals(manifest)) {
                                                    throw new IllegalStateException(
                                                            "Unexpected collision with manifest.json");
                                                }
                                                freturn.addAttachmentFile(f, contentType);
                                                parent.put(defn.getElementName(), f.getName());
                                            }
                                        } else {
                                            throw new IllegalStateException("Unhandled transform case");
                                        }
                                    }
                                }
                            }
                        }

                        datestamp = (new SimpleDateFormat(ISO8601_DATE_FORMAT, Locale.US))
                                .format(new Date(TableConstants.milliSecondsFromNanos(savepointTimestamp)));

                        // For XML, we traverse the map to serialize it
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        DocumentBuilder docBuilder = dbf.newDocumentBuilder();

                        Document d = docBuilder.newDocument();

                        d.setXmlStandalone(true);

                        Element e = d.createElement((xmlRootElementName == null) ? "data" : xmlRootElementName);
                        d.appendChild(e);
                        e.setAttribute("id", tableId);
                        DynamicPropertiesCallback cb = new DynamicPropertiesCallback(appName, tableId,
                                instanceId, activeUser, currentLocale, username, userEmail);

                        int idx = 0;
                        Element meta = d.createElementNS(XML_OPENROSA_NAMESPACE, "meta");
                        meta.setPrefix("jr");

                        Element v = d.createElementNS(XML_OPENROSA_NAMESPACE, "instanceID");
                        Text txtNode = d.createTextNode(submissionInstanceId);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        if (xmlDeviceIdPropertyName != null) {
                            String deviceId = propertyManager.getSingularProperty(xmlDeviceIdPropertyName, cb);
                            if (deviceId != null) {
                                v = d.createElementNS(XML_OPENROSA_NAMESPACE, "deviceID");
                                txtNode = d.createTextNode(deviceId);
                                v.appendChild(txtNode);
                                meta.appendChild(v);
                            }
                        }
                        if (xmlUserIdPropertyName != null) {
                            String userId = propertyManager.getSingularProperty(xmlUserIdPropertyName, cb);
                            if (userId != null) {
                                v = d.createElementNS(XML_OPENROSA_NAMESPACE, "userID");
                                txtNode = d.createTextNode(userId);
                                v.appendChild(txtNode);
                                meta.appendChild(v);
                            }
                        }
                        v = d.createElementNS(XML_OPENROSA_NAMESPACE, "timeEnd");
                        txtNode = d.createTextNode(datestamp);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // these are extra metadata tags...
                        if (instanceName != null) {
                            v = d.createElement("instanceName");
                            txtNode = d.createTextNode(instanceName);
                            v.appendChild(txtNode);
                            meta.appendChild(v);
                        } else {
                            v = d.createElement("instanceName");
                            txtNode = d.createTextNode(savepointTimestamp);
                            v.appendChild(txtNode);
                            meta.appendChild(v);
                        }

                        // these are extra metadata tags...
                        // rowID
                        v = d.createElement("rowID");
                        txtNode = d.createTextNode(instanceId);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // rowETag
                        v = d.createElement("rowETag");
                        if (rowETag != null) {
                            txtNode = d.createTextNode(rowETag);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // filterType
                        v = d.createElement("filterType");
                        if (filterType != null) {
                            txtNode = d.createTextNode(filterType);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // filterValue
                        v = d.createElement("filterValue");
                        if (filterValue != null) {
                            txtNode = d.createTextNode(filterValue);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // formID
                        v = d.createElement("formID");
                        txtNode = d.createTextNode(formId);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // locale
                        v = d.createElement("locale");
                        txtNode = d.createTextNode(locale);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // savepointType
                        v = d.createElement("savepointType");
                        txtNode = d.createTextNode(savepointType);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // savepointCreator
                        v = d.createElement("savepointCreator");
                        if (savepointCreator != null) {
                            txtNode = d.createTextNode(savepointCreator);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // savepointTimestamp
                        v = d.createElement("savepointTimestamp");
                        txtNode = d.createTextNode(savepointTimestamp);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // and insert the meta block into the XML

                        e.appendChild(meta);

                        idx = 3;
                        ArrayList<String> entryNames = new ArrayList<String>();
                        entryNames.addAll(values.keySet());
                        Collections.sort(entryNames);
                        for (String name : entryNames) {
                            idx = generateXmlHelper(d, e, idx, name, values, logger);
                        }

                        TransformerFactory factory = TransformerFactory.newInstance();
                        Transformer transformer = factory.newTransformer();
                        Properties outFormat = new Properties();
                        outFormat.setProperty(OutputKeys.INDENT, "no");
                        outFormat.setProperty(OutputKeys.METHOD, "xml");
                        outFormat.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                        outFormat.setProperty(OutputKeys.VERSION, "1.0");
                        outFormat.setProperty(OutputKeys.ENCODING, "UTF-8");
                        transformer.setOutputProperties(outFormat);

                        ByteArrayOutputStream out = new ByteArrayOutputStream();

                        DOMSource domSource = new DOMSource(d.getDocumentElement());
                        StreamResult result = new StreamResult(out);
                        transformer.transform(domSource, result);

                        out.flush();
                        out.close();

                        b.append(out.toString(CharEncoding.UTF_8));

                        // OK we have the document in the builder (b).
                        String doc = b.toString();

                        freturn.instanceFile = submissionXml;

                        // see if the form is encrypted and we can
                        // encrypt it...
                        EncryptedFormInformation formInfo = EncryptionUtils.getEncryptedFormInformation(appName,
                                tableId, xmlBase64RsaPublicKey, instanceId);
                        if (formInfo != null) {
                            File submissionXmlEnc = new File(submissionXml.getParentFile(),
                                    submissionXml.getName() + ".enc");
                            submissionXmlEnc.delete();
                            // if we are encrypting, the form cannot be
                            // reopened afterward
                            // and encrypt the submission (this is a
                            // one-way operation)...
                            if (!EncryptionUtils.generateEncryptedSubmission(freturn, doc, submissionXml,
                                    submissionXmlEnc, formInfo)) {
                                return null;
                            }
                            // at this point, the freturn object has
                            // been re-written with the encrypted media
                            // and xml files.
                        } else {
                            exportFile(doc, submissionXml, logger);
                        }

                    } else {
                        // Pre-processing -- collapse all mimeUri into filename
                        for (ColumnDefinition defn : orderedDefns.getColumnDefinitions()) {
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();

                            if (dataType == ElementDataType.object && type.getElementType().equals("mimeUri")) {
                                Map<String, Object> parent = null;
                                List<ColumnDefinition> parents = new ArrayList<ColumnDefinition>();
                                ColumnDefinition d = defn.getParent();
                                while (d != null) {
                                    parents.add(d);
                                    d = d.getParent();
                                }
                                parent = values;
                                for (int i = parents.size() - 1; i >= 0; --i) {
                                    Object o = parent.get(parents.get(i).getElementName());
                                    if (o == null) {
                                        parent = null;
                                        break;
                                    }
                                    parent = (Map<String, Object>) o;
                                }
                                if (parent != null) {
                                    Object o = parent.get(defn.getElementName());
                                    if (o != null) {
                                        if (dataType == ElementDataType.object
                                                && type.getElementType().equals("mimeUri")) {
                                            Map<String, Object> mimeuri = (Map<String, Object>) o;
                                            String uriFragment = (String) mimeuri.get("uriFragment");
                                            String contentType = (String) mimeuri.get("contentType");
                                            File f = ODKFileUtils.getAsFile(appName, uriFragment);
                                            if (f.equals(manifest)) {
                                                throw new IllegalStateException(
                                                        "Unexpected collision with manifest.json");
                                            }
                                            freturn.addAttachmentFile(f, contentType);
                                            parent.put(defn.getElementName(), f.getName());
                                        } else {
                                            throw new IllegalStateException("Unhandled transform case");
                                        }
                                    }
                                }
                            }
                        }

                        // For JSON, we construct the model, then emit model +
                        // meta + data
                        HashMap<String, Object> wrapper = new HashMap<String, Object>();
                        wrapper.put("tableId", tableId);
                        wrapper.put("instanceId", instanceId);
                        HashMap<String, Object> formDef = new HashMap<String, Object>();
                        formDef.put("table_id", tableId);
                        formDef.put("model", orderedDefns.getDataModel());
                        wrapper.put("formDef", formDef);
                        wrapper.put("data", values);
                        wrapper.put("metadata", new HashMap<String, Object>());
                        HashMap<String, Object> elem = (HashMap<String, Object>) wrapper.get("metadata");
                        if (instanceName != null) {
                            elem.put("instanceName", instanceName);
                        }
                        elem.put("saved", "COMPLETE");
                        elem.put("timestamp", datestamp);

                        b.append(ODKFileUtils.mapper.writeValueAsString(wrapper));

                        // OK we have the document in the builder (b).
                        String doc = b.toString();
                        exportFile(doc, submissionXml, logger);
                    }
                    exportFile(freturn.serializeUriFragmentList(getContext()), manifest, logger);
                    return ParcelFileDescriptor.open(manifest, ParcelFileDescriptor.MODE_READ_ONLY);

                }
            } finally {
                if (c != null && !c.isClosed()) {
                    c.close();
                    c = null;
                }
            }

        } catch (ParserConfigurationException e) {
            logger.printStackTrace(e);
        } catch (TransformerException e) {
            logger.printStackTrace(e);
        } catch (JsonParseException e) {
            logger.printStackTrace(e);
        } catch (JsonMappingException e) {
            logger.printStackTrace(e);
        } catch (IOException e) {
            logger.printStackTrace(e);
        }

    } finally {
        if (db != null) {
            try {
                // release the reference...
                // this does not necessarily close the db handle
                // or terminate any pending transaction
                db.releaseReference();
            } finally {
                // this will release the final reference and close the database
                OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().removeConnection(appName,
                        dbHandleName);
            }
        }
    }
    return null;
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

private BaseTable buildBaseTable(OdkConnectionInterface db, Cursor c, String tableId, boolean canCreateRow) {

    HashMap<String, Integer> mElementKeyToIndex = null;
    String[] mElementKeyForIndex = null;

    if (!c.moveToFirst()) {

        // Attempt to retrieve the columns from the cursor.
        // These may not be available if there were no rows returned.
        // It depends upon the cursor implementation.
        try {/*from  ww  w.ja v a  2  s.  co  m*/
            int columnCount = c.getColumnCount();
            mElementKeyForIndex = new String[columnCount];
            mElementKeyToIndex = new HashMap<>(columnCount);
            int i;

            for (i = 0; i < columnCount; ++i) {
                String columnName = c.getColumnName(i);
                mElementKeyForIndex[i] = columnName;
                mElementKeyToIndex.put(columnName, i);
            }
        } catch (Exception e) {
            // ignore.
        }

        // if they were not available, declare an empty array.
        if (mElementKeyForIndex == null) {
            mElementKeyForIndex = new String[0];
        }
        c.close();

        // we have no idea what the table should contain because it has no rows...
        BaseTable table = new BaseTable(null, mElementKeyForIndex, mElementKeyToIndex, 0);
        table.setEffectiveAccessCreateRow(canCreateRow);
        return table;
    }

    int rowCount = c.getCount();
    int columnCount = c.getColumnCount();

    BaseTable table = null;

    // These maps will map the element key to the corresponding index in
    // either data or metadata. If the user has defined a column with the
    // element key _my_data, and this column is at index 5 in the data
    // array, dataKeyToIndex would then have a mapping of _my_data:5.
    // The sync_state column, if present at index 7, would have a mapping
    // in metadataKeyToIndex of sync_state:7.
    mElementKeyForIndex = new String[columnCount];
    mElementKeyToIndex = new HashMap<>(columnCount);

    int i;

    for (i = 0; i < columnCount; ++i) {
        String columnName = c.getColumnName(i);
        mElementKeyForIndex[i] = columnName;
        mElementKeyToIndex.put(columnName, i);
    }

    table = new BaseTable(null, mElementKeyForIndex, mElementKeyToIndex, rowCount);

    String[] rowData = new String[columnCount];
    do {
        // First get the user-defined data for this row.
        for (i = 0; i < columnCount; i++) {
            String value = CursorUtils.getIndexAsString(c, i);
            rowData[i] = value;
        }

        Row nextRow = new Row(rowData.clone(), table);
        table.addRow(nextRow);
    } while (c.moveToNext());
    c.close();

    table.setEffectiveAccessCreateRow(canCreateRow);

    return table;
}

From source file:org.opendatakit.services.database.utlities.ODKDatabaseImplUtils.java

/**
 * Inserts a checkpoint row for the given rowId in the tableId. Checkpoint
 * rows are created by ODK Survey to hold intermediate values during the
 * filling-in of the form. They act as restore points in the Survey, should
 * the application die.//from  ww  w .  j  a  v  a 2  s .  c  o  m
 *
 * @param db
 * @param tableId
 * @param orderedColumns
 * @param cvValues
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @param locale
 */
public void insertCheckpointRowWithId(OdkConnectionInterface db, String tableId, OrderedColumns orderedColumns,
        ContentValues cvValues, String rowId, String activeUser, String rolesList, String locale)
        throws ActionNotAuthorizedException {

    if (cvValues.size() <= 0) {
        throw new IllegalArgumentException(t + ": No values to add into table for checkpoint" + tableId);
    }

    // these are all managed in the database layer...
    // the user should NOT set them...

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint timestamp can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint type can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.ROW_ETAG)) {
        throw new IllegalArgumentException(t + ": No user supplied row ETag can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SYNC_STATE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied sync state can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.CONFLICT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied conflict type can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.FILTER_VALUE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied filter value can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.FILTER_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied filter type can be included for a checkpoint");
    }

    // If a rowId is specified, a cursor will be needed to
    // get the current row to create a checkpoint with the relevant data
    Cursor c = null;
    try {
        // Allow the user to pass in no rowId if this is the first
        // checkpoint row that the user is adding
        if (rowId == null) {

            // TODO: is this even valid any more? I think we disallow this in the AIDL flow.

            String rowIdToUse = LocalizationUtils.genUUID();
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowIdToUse);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null);
            return;
        }

        StringBuilder b = new StringBuilder();
        b.append(K_DATATABLE_ID_EQUALS_PARAM).append(S_AND).append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                .append(" IN (SELECT MAX(").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                .append(tableId).append(K_WHERE).append(K_DATATABLE_ID_EQUALS_PARAM).append(")");
        c = db.query(tableId, null, b.toString(), new Object[] { rowId, rowId }, null, null, null, null);
        c.moveToFirst();

        if (c.getCount() > 1) {
            throw new IllegalStateException(t + ": More than one checkpoint at a timestamp");
        }

        // Inserting a checkpoint for the first time
        if (c.getCount() <= 0) {
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowId);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null);
            return;
        } else {
            // Make sure that the conflict_type of any existing row
            // is null, otherwise throw an exception
            int conflictIndex = c.getColumnIndex(DataTableColumns.CONFLICT_TYPE);
            if (!c.isNull(conflictIndex)) {
                throw new IllegalStateException(
                        t + ":  A checkpoint cannot be added for a row that is in conflict");
            }

            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }

            // This is unnecessary
            // We should only have one row at this point
            //c.moveToFirst();

            String priorFilterType = null;
            String priorFilterValue = null;

            // Get the number of columns to iterate over and add
            // those values to the content values
            for (int i = 0; i < c.getColumnCount(); i++) {
                String name = c.getColumnName(i);

                if (currValues.containsKey(name)) {
                    continue;
                }

                // omitting savepoint timestamp will generate a new timestamp.
                if (name.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                    continue;
                }

                // set savepoint type to null to mark this as a checkpoint
                if (name.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                    currValues.put(name, null);
                    continue;
                }

                // sync state (a non-null field) should either remain 'new_row'
                // or be set to 'changed' for all other existing values.
                if (name.equals(DataTableColumns.SYNC_STATE)) {
                    String priorState = c.getString(i);
                    if (priorState.equals(SyncState.new_row.name())) {
                        currValues.put(name, SyncState.new_row.name());
                    } else {
                        currValues.put(name, SyncState.changed.name());
                    }
                    continue;
                }

                if (c.isNull(i)) {
                    currValues.put(name, null);
                    continue;
                }

                // otherwise, just copy the values over...
                Class<?> theClass = CursorUtils.getIndexDataType(c, i);
                Object object = CursorUtils.getIndexAsType(c, theClass, i);
                insertValueIntoContentValues(currValues, theClass, name, object);

                if (name.equals(DataTableColumns.FILTER_TYPE)) {
                    priorFilterType = c.getString(i);
                }

                if (name.equals(DataTableColumns.FILTER_VALUE)) {
                    priorFilterValue = c.getString(i);
                }
            }

            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, false, priorFilterType, priorFilterValue);
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Inserts a checkpoint row for the given rowId in the tableId. Checkpoint
 * rows are created by ODK Survey to hold intermediate values during the
 * filling-in of the form. They act as restore points in the Survey, should
 * the application die.//from   w ww.java2s. co m
 *
 * @param db
 * @param tableId
 * @param orderedColumns
 * @param cvValues
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @param locale
 */
public void insertCheckpointRowWithId(OdkConnectionInterface db, String tableId, OrderedColumns orderedColumns,
        ContentValues cvValues, String rowId, String activeUser, String rolesList, String locale)
        throws ActionNotAuthorizedException {

    if (cvValues.size() <= 0) {
        throw new IllegalArgumentException(t + ": No values to add into table for checkpoint" + tableId);
    }

    // these are all managed in the database layer...
    // the user should NOT set them...

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint timestamp can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint type can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.ROW_ETAG)) {
        throw new IllegalArgumentException(t + ": No user supplied row ETag can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SYNC_STATE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied sync state can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.CONFLICT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied conflict type can be included for a checkpoint");
    }

    // If a rowId is specified, a cursor will be needed to
    // get the current row to create a checkpoint with the relevant data
    Cursor c = null;
    try {
        // Allow the user to pass in no rowId if this is the first
        // checkpoint row that the user is adding
        if (rowId == null) {

            // TODO: is this even valid any more? I think we disallow this in the AIDL flow.

            String rowIdToUse = LocalizationUtils.genUUID();
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowIdToUse);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null, null, null, null);
            return;
        }

        StringBuilder b = new StringBuilder();
        b.append(K_DATATABLE_ID_EQUALS_PARAM).append(S_AND).append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                .append(" IN (SELECT MAX(").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                .append(tableId).append(K_WHERE).append(K_DATATABLE_ID_EQUALS_PARAM).append(")");
        c = db.query(tableId, null, b.toString(), new Object[] { rowId, rowId }, null, null, null, null);
        c.moveToFirst();

        if (c.getCount() > 1) {
            throw new IllegalStateException(t + ": More than one checkpoint at a timestamp");
        }

        // Inserting a checkpoint for the first time
        if (c.getCount() <= 0) {
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowId);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null, null, null, null);
            return;
        } else {
            // Make sure that the conflict_type of any existing row
            // is null, otherwise throw an exception
            int conflictIndex = c.getColumnIndex(DataTableColumns.CONFLICT_TYPE);
            if (!c.isNull(conflictIndex)) {
                throw new IllegalStateException(
                        t + ":  A checkpoint cannot be added for a row that is in conflict");
            }

            // these are all managed in the database layer...
            // the user should NOT set them...

            if (cvValues.containsKey(DataTableColumns.DEFAULT_ACCESS)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied default access can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.ROW_OWNER)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied row owner can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.GROUP_READ_ONLY)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied group read only can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.GROUP_MODIFY)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied group modify can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.GROUP_PRIVILEGED)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied group privileged can be included for a checkpoint");
            }

            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }

            // This is unnecessary
            // We should only have one row at this point
            //c.moveToFirst();

            String priorDefaultAccess = null;
            String priorOwner = null;
            String priorGroupReadOnly = null;
            String priorGroupModify = null;
            String priorGroupPrivileged = null;

            // Get the number of columns to iterate over and add
            // those values to the content values
            for (int i = 0; i < c.getColumnCount(); i++) {
                String name = c.getColumnName(i);

                if (name.equals(DataTableColumns.DEFAULT_ACCESS)) {
                    priorDefaultAccess = c.getString(i);
                }

                if (name.equals(DataTableColumns.ROW_OWNER)) {
                    priorOwner = c.getString(i);
                }

                if (name.equals(DataTableColumns.GROUP_READ_ONLY)) {
                    priorGroupReadOnly = c.getString(i);
                }

                if (name.equals(DataTableColumns.GROUP_MODIFY)) {
                    priorGroupModify = c.getString(i);
                }

                if (name.equals(DataTableColumns.GROUP_PRIVILEGED)) {
                    priorGroupPrivileged = c.getString(i);
                }

                if (currValues.containsKey(name)) {
                    continue;
                }

                // omitting savepoint timestamp will generate a new timestamp.
                if (name.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                    continue;
                }

                // set savepoint type to null to mark this as a checkpoint
                if (name.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                    currValues.put(name, null);
                    continue;
                }

                // sync state (a non-null field) should either remain 'new_row'
                // or be set to 'changed' for all other existing values.
                if (name.equals(DataTableColumns.SYNC_STATE)) {
                    String priorState = c.getString(i);
                    if (priorState.equals(SyncState.new_row.name())) {
                        currValues.put(name, SyncState.new_row.name());
                    } else {
                        currValues.put(name, SyncState.changed.name());
                    }
                    continue;
                }

                if (c.isNull(i)) {
                    currValues.put(name, null);
                    continue;
                }

                // otherwise, just copy the values over...
                Class<?> theClass = CursorUtils.getIndexDataType(c, i);
                Object object = CursorUtils.getIndexAsType(c, theClass, i);
                insertValueIntoContentValues(currValues, theClass, name, object);
            }

            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, false, priorDefaultAccess, priorOwner, priorGroupReadOnly, priorGroupModify,
                    priorGroupPrivileged);
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
}