org.opendatakit.sensors.manager.WorkerThread.java Source code

Java tutorial

Introduction

Here is the source code for org.opendatakit.sensors.manager.WorkerThread.java

Source

/*
 * Copyright (C) 2013 University of Washington
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.opendatakit.sensors.manager;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.json.JSONObject;
import org.opendatakit.aggregate.odktables.rest.ElementDataType;
import org.opendatakit.aggregate.odktables.rest.ElementType;
import org.opendatakit.common.android.data.ColumnDefinition;
import org.opendatakit.common.android.database.DatabaseFactory;
import org.opendatakit.common.android.provider.DataTableColumns;
import org.opendatakit.common.android.utilities.ODKDataUtils;
import org.opendatakit.common.android.utilities.ODKDatabaseUtils;
import org.opendatakit.common.android.utilities.ODKJsonNames;
import org.opendatakit.common.android.utilities.TableUtil;
import org.opendatakit.sensors.DataSeries;
import org.opendatakit.sensors.DriverType;
import org.opendatakit.sensors.ODKSensor;

import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;

/**
 * 
 * @author wbrunette@gmail.com
 * @author rohitchaudhri@gmail.com
 * 
 */
public class WorkerThread extends Thread {
    private static final String TAG = "WorkerThread";

    private boolean isRunning;
    private Context serviceContext;
    private ODKSensorManager sensorManager;

    public WorkerThread(Context context, ODKSensorManager manager) {
        super("WorkerThread");
        isRunning = true;
        serviceContext = context;
        sensorManager = manager;
    }

    public void stopthread() {
        isRunning = false;
        this.interrupt();
    }

    @Override
    public void run() {
        Log.d(TAG, "worker thread started");

        while (isRunning) {
            try {
                for (ODKSensor sensor : sensorManager.getSensorsUsingAppForDatabase()) {
                    moveSensorDataToCP(sensor);
                }

                Thread.sleep(3000);
            } catch (InterruptedException iex) {
                iex.printStackTrace();
            }
        }
    }

    private void moveSensorDataToCP(ODKSensor aSensor) {
        if (aSensor != null) {
            List<Bundle> bundles = aSensor.getSensorData(0);// XXX for now this gets
                                                            // all data fm sensor
            if (bundles == null) {
                Log.e(TAG, "WTF null list of bundles~");
            } else {
                Iterator<Bundle> iter = bundles.iterator();
                while (iter.hasNext()) {
                    Bundle aBundle = iter.next();

                    DriverType driver = sensorManager.getSensorDriverType(aSensor.getSensorID());
                    if (driver != null && driver.getTableDefinitionStr() != null) {
                        parseSensorDataAndInsertIntoTable(aSensor, driver.getTableDefinitionStr(), aBundle);
                    }

                }
            }
        }
    }

    private void parseSensorDataAndInsertIntoTable(ODKSensor aSensor, String strTableDef, Bundle dataBundle) {
        JSONObject jsonTableDef = null;
        ContentValues tablesValues = new ContentValues();

        SQLiteDatabase db = null;
        try {
            db = DatabaseFactory.get().getDatabase(serviceContext, aSensor.getAppNameForDatabase());

            jsonTableDef = new JSONObject(strTableDef);

            String tableId = jsonTableDef.getJSONObject(ODKJsonNames.jsonTableStr)
                    .getString(ODKJsonNames.jsonTableIdStr);

            if (tableId == null) {
                return;
            }

            boolean success;

            success = false;
            try {
                success = ODKDatabaseUtils.get().hasTableId(db, tableId);
            } catch (Exception e) {
                e.printStackTrace();
                throw new SQLException("Exception testing for tableId " + tableId);
            }
            if (!success) {
                sensorManager.parseDriverTableDefintionAndCreateTable(aSensor.getSensorID(),
                        aSensor.getAppNameForDatabase(), db);
            }

            success = false;
            try {
                success = ODKDatabaseUtils.get().hasTableId(db, tableId);
            } catch (Exception e) {
                e.printStackTrace();
                throw new SQLException("Exception testing for tableId " + tableId);
            }
            if (!success) {
                throw new SQLException("Unable to create tableId " + tableId);
            }

            ArrayList<ColumnDefinition> orderedDefs = TableUtil.get().getColumnDefinitions(db,
                    aSensor.getAppNameForDatabase(), tableId);

            // Create the columns for the driver table
            for (ColumnDefinition col : orderedDefs) {
                if (!col.isUnitOfRetention()) {
                    continue;
                }

                String colName = col.getElementKey();
                ElementType type = col.getType();

                if (colName.equals(DataSeries.SENSOR_ID)) {

                    // special treatment
                    tablesValues.put(colName, aSensor.getSensorID());

                } else if (type.getDataType() == ElementDataType.bool) {

                    Boolean boolColData = dataBundle.containsKey(colName) ? dataBundle.getBoolean(colName) : null;
                    Integer colData = (boolColData == null) ? null : (boolColData ? 1 : 0);
                    tablesValues.put(colName, colData);

                } else if (type.getDataType() == ElementDataType.integer) {

                    Integer colData = dataBundle.containsKey(colName) ? dataBundle.getInt(colName) : null;
                    tablesValues.put(colName, colData);

                } else if (type.getDataType() == ElementDataType.number) {

                    Double colData = dataBundle.containsKey(colName) ? dataBundle.getDouble(colName) : null;
                    tablesValues.put(colName, colData);

                } else {
                    // everything else is a string value coming across the wire...
                    String colData = dataBundle.containsKey(colName) ? dataBundle.getString(colName) : null;
                    tablesValues.put(colName, colData);
                }
            }

            if (tablesValues.size() > 0) {
                Log.i(TAG, "Writing db values for sensor:" + aSensor.getSensorID());
                String rowId = tablesValues.containsKey(DataTableColumns.ID)
                        ? tablesValues.getAsString(DataTableColumns.ID)
                        : null;
                if (rowId == null) {
                    rowId = ODKDataUtils.genUUID();
                }
                ODKDatabaseUtils.get().insertDataIntoExistingDBTableWithId(db, tableId, orderedDefs, tablesValues,
                        rowId);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.close();
            }
        }
    }
}