org.rapidandroid.tests.ContentBootstrapTests.java Source code

Java tutorial

Introduction

Here is the source code for org.rapidandroid.tests.ContentBootstrapTests.java

Source

/*
 * Copyright (C) 2009 Dimagi Inc., UNICEF
 *
 * 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.
 *
 */

/**
 * @author Daniel Myung dmyung@dimagi.com
 * @created Jan 21, 2009
 * Summary:
 */
package org.rapidandroid.tests;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Random;
import java.util.Vector;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.rapidandroid.content.translation.ModelTranslator;
import org.rapidandroid.data.RapidSmsDBConstants;
import org.rapidsms.java.core.model.Field;
import org.rapidsms.java.core.model.Form;
import org.rapidsms.java.core.model.SimpleFieldType;
import org.rapidsms.java.core.parser.service.ParsingService.ParserType;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

/**
 * @author dmyung
 * @created Jan 21, 2009
 */
public class ContentBootstrapTests extends AndroidTestCase {

    protected String loadAssetFile(String filename) {
        try {
            InputStream is = getContext().getAssets().open(filename);

            int size = is.available();

            // Read the entire asset into a local byte buffer.
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();

            // Convert the buffer into a Java string.
            String text = new String(buffer);

            return text;

        } catch (IOException e) {
            // Should never happen!
            throw new RuntimeException(e);
        }

    }

    // public void test000BootstrapFieldTypes() {
    // String types = loadAssetFile("definitions/fieldtypes.json");
    // HashMap<Integer, SimpleFieldType> typeHash = new
    // HashMap<Integer,SimpleFieldType>();
    //      
    // parseFieldTypes(types, typeHash);
    // }

    // First level bootstrap of Form definitions into DB.
    public void test000BootstrapFormsAndInsertIntoDB() {
        ModelTranslator.ClearFormTables();

        String fields = loadAssetFile("definitions/fields.json");// "[{\"pk\": 1, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 1, \"prompt\": \"Location of distribution center\", \"name\": \"Location\", \"form\": 1, \"sequence\": 1}}, {\"pk\": 2, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 2, \"prompt\": \"Number of bednets received\", \"name\": \"received\", \"form\": 1, \"sequence\": 2}}, {\"pk\": 3, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 2, \"prompt\": \"Number of bednets that have been handed out\", \"name\": \"given\", \"form\": 1, \"sequence\": 3}}, {\"pk\": 4, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 2, \"prompt\": \"Number of bednets that remain in balance\", \"name\": \"balance\", \"form\": 1, \"sequence\": 4}}, {\"pk\": 5, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 1, \"prompt\": \"Child Identifier (6 digits)\", \"name\": \"child_id\", \"form\": 2, \"sequence\": 1}}, {\"pk\": 6, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 3, \"prompt\": \"weight\", \"name\": \"weight\", \"form\": 2, \"sequence\": 2}}, {\"pk\": 7, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 4, \"prompt\": \"height\", \"name\": \"height\", \"form\": 2, \"sequence\": 3}}, {\"pk\": 8, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 5, \"prompt\": \"ratio\", \"name\": \"ratio\", \"form\": 2, \"sequence\": 4}}, {\"pk\": 9, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 6, \"prompt\": \"muac\", \"name\": \"muac\", \"form\": 2, \"sequence\": 5}}, {\"pk\": 10, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 7, \"prompt\": \"Does child suffer from oedema\", \"name\": \"oedema\", \"form\": 2, \"sequence\": 6}}, {\"pk\": 11, \"model\": \"rapidandroid.field\", \"fields\": {\"fieldtype\": 7, \"prompt\": \"does the child suffer from diarrhoea\", \"name\": \"diarrhoea\", \"form\": 2, \"sequence\": 7}}]";
        String forms = loadAssetFile("definitions/forms.json");// "[{\"pk\": 1, \"model\": \"rapidandroid.form\", \"fields\": {\"parsemethod\": \"simpleregex\", \"prefix\": \"bednets\", \"description\": \"Bednet Distribution(supply)\", \"formname\": \"bednets\"}}, {\"pk\": 2, \"model\": \"rapidandroid.form\", \"fields\": {\"parsemethod\": \"simpleregex\", \"prefix\": \"nutrition\", \"description\": \"Nutrition Information (monitorin and evaluation)\", \"formname\": \"Nutrition\"}}]";
        String types = loadAssetFile("definitions/fieldtypes.json");// "[{\"pk\": 1, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"word\", \"regex\": \"\\w+\", \"name\": \"word\"}}, {\"pk\": 2, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"number\", \"regex\": \"\\d+\", \"name\": \"number\"}}, {\"pk\": 3, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"float\", \"regex\": \"(\\d+{1,3})(?c:\\s*(kg|kilo|kilos|lb|lbs|pounds))\", \"name\": \"weight\"}}, {\"pk\": 4, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"integer\", \"regex\": \"(\\d+{1,3})(?:\\s*(cm|m|in))\", \"name\": \"height\"}}, {\"pk\": 5, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"float\", \"regex\": \"(\\d+\\:\\d+)|(\\d+\\/\\d+)\", \"name\": \"ratio\"}}, {\"pk\": 6, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"integer\", \"regex\": \"(\\d+{1,3})(?:\\s*(cm|mm|m|in|ft|feet|meter|meters))\", \"name\": \"length\"}}, {\"pk\": 7, \"model\": \"rapidandroid.fieldtype\", \"fields\": {\"datatype\": \"boolean\", \"regex\": \"(t|f|true|false|y|n|yes|no)\", \"name\": \"boolean\"}}]";

        //      String formdefs = "";

        @SuppressLint("UseSparseArrays")
        HashMap<Integer, SimpleFieldType> typeHash = new HashMap<Integer, SimpleFieldType>();
        //      HashMap<Integer, Field> fieldHash = new HashMap<Integer, Field>();
        //      HashMap<Integer, Form> formHash = new HashMap<Integer, Form>();
        @SuppressLint("UseSparseArrays")
        HashMap<Integer, Vector<Field>> fieldToFormHash = new HashMap<Integer, Vector<Field>>();
        Vector<Form> allforms = new Vector<Form>();

        //      boolean fail = false;

        parseFieldTypes(types, typeHash);
        parseFields(fields, typeHash, fieldToFormHash);
        parseForms(forms, fieldToFormHash, allforms);

        assertEquals(2, allforms.size());
        Log.d("dimagi", "Test bootstrap success");

        insertFormsIntoDb(allforms);
    }

    public void test004GetFormsFromDBAndPutIntoModel() {
        // Regenerate the form definitions
        test000BootstrapFormsAndInsertIntoDB();

        Log.d("dimagi", "************ getting forms from the db");
        Uri query = RapidSmsDBConstants.Form.CONTENT_URI;
        Cursor cr = getContext().getContentResolver().query(query, null, null, null, null);
        assertEquals(2, cr.getCount());

        // next get the ids

        cr.moveToFirst();

        do {
            int id = cr.getInt(0); // presumably the id
            Uri directUri = Uri.parse(RapidSmsDBConstants.Form.CONTENT_URI_STRING + id);
            Log.d("dimagi", "Querying for form: " + directUri);
            Form f = ModelTranslator.getFormFromUri(directUri);

            assertNotNull(f);
            assertNotNull(f.getFields());
        } while (cr.moveToNext());
        cr.close();
    }

    public void test005RegenerateTablesForForms() {
        // todo: blow away the formdata tables
        // recreate the tables from the form definition

        test000BootstrapFormsAndInsertIntoDB();

        Uri query = RapidSmsDBConstants.Form.CONTENT_URI;
        Cursor cr = getContext().getContentResolver().query(query, null, null, null, null);
        cr.moveToFirst();

        do {
            int id = cr.getInt(0); // presumably the id
            Uri directUri = Uri.parse(RapidSmsDBConstants.Form.CONTENT_URI_STRING + id);

            Form f = ModelTranslator.getFormFromUri(directUri);
            Log.d("dimagi", "Generating formData table for form: " + f.getFormName());
            ModelTranslator.generateFormTable(f);
        } while (cr.moveToNext());
        // mProv.ClearFormDataDebug(); //see if this crashes
        cr.close();
    }

    /**
     * @param forms
     * @param fieldToFormHash
     * @param allforms
     */
    private void parseForms(String forms, HashMap<Integer, Vector<Field>> fieldToFormHash, Vector<Form> allforms) {
        // ok, let's get the forms
        try {
            JSONArray formarray = new JSONArray(forms);
            int arrlength = formarray.length();
            for (int i = 0; i < arrlength; i++) {
                try {
                    JSONObject obj = formarray.getJSONObject(i);

                    if (!obj.getString("model").equals("rapidandroid.form")) {
                        assertTrue(false);
                    }

                    int pk = obj.getInt("pk");
                    Integer pkInt = Integer.valueOf(pk);
                    JSONObject jsonfields = obj.getJSONObject("fields");

                    // public Form(int id, String name, String prefix, String
                    // desc, String parsetype, Field[] fields)

                    //               int formcount = 0;
                    Field[] fieldarr = new Field[fieldToFormHash.get(pkInt).size()];
                    for (int q = 0; q < fieldarr.length; q++) {
                        fieldarr[q] = fieldToFormHash.get(pkInt).get(q);
                    }
                    Form newform = new Form(pk, jsonfields.getString("formname"), jsonfields.getString("prefix"),
                            jsonfields.getString("description"), fieldarr, ParserType.SIMPLEREGEX);
                    allforms.add(newform);

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    Log.d("dimagi", e.getMessage());
                    assertTrue(false);
                }
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            Log.d("testBootstrapForms.formsouter", e.getMessage());
            assertTrue(false);
        }
    }

    /**
     * @param fields
     * @param typeHash
     * @param fieldToFormHash
     */
    private void parseFields(String fields, HashMap<Integer, SimpleFieldType> typeHash,
            HashMap<Integer, Vector<Field>> fieldToFormHash) {
        // ok, let's get the fields
        try {
            JSONArray fieldsarray = new JSONArray(fields);
            int arrlength = fieldsarray.length();
            for (int i = 0; i < arrlength; i++) {
                try {
                    JSONObject obj = fieldsarray.getJSONObject(i);

                    if (!obj.getString("model").equals("rapidandroid.field")) {
                        assertTrue(false);
                    }

                    int pk = obj.getInt("pk");

                    JSONObject jsonfields = obj.getJSONObject("fields");
                    int form_id = jsonfields.getInt("form");
                    // public Field(int id, int sequence, String name, String
                    // prompt, SimpleFieldType ftype) {
                    Field newfield = new Field(pk, jsonfields.getInt("sequence"), jsonfields.getString("name"),
                            jsonfields.getString("prompt"),
                            typeHash.get(Integer.valueOf(jsonfields.getInt("fieldtype"))));

                    // fieldHash.put(new Integer(pk), newfield);
                    Integer formInt = Integer.valueOf(form_id);
                    if (!fieldToFormHash.containsKey(formInt)) {
                        fieldToFormHash.put(formInt, new Vector<Field>());
                        Log.d("dimagi", "### adding a key again?!" + formInt);
                    }
                    fieldToFormHash.get(formInt).add(newfield);
                    Log.d("dimagi", "#### Parsed field: " + newfield.getFieldId() + " [" + newfield.getName()
                            + "] newlength: " + fieldToFormHash.get(formInt).size());

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    Log.d("dimagi", e.getMessage());
                    assertTrue(false);
                }
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            Log.d("dimagi", e.getMessage());
            assertTrue(false);
        }
    }

    /**
     * @param types
     * @param typeHash
     */
    private void parseFieldTypes(String types, HashMap<Integer, SimpleFieldType> typeHash) {
        // ok, let's get the field types
        // HashMap <String, String> hackRegexHash = new HashMap<String,
        // String>();
        //      
        // hackRegexHash.put("boolean","^(t|f|true|false|y|no|yes|n|n0)(\\s|$)");
        // hackRegexHash.put("length","^(\\d+)(\\s*(cm|m))($|\\s)");
        // hackRegexHash.put("ratio","^((\\d+\\:\\d+)|(\\d+\\/\\d+)|(\\d+\\s*%)|(\\d+\\s*pct))");
        // hackRegexHash.put("height","^(\\d+)(\\s*(cm|mm|meter|meters))($|\\s)");
        // hackRegexHash.put("weight","^(\\d+)(\\s*(kg|kilo|kilos))");
        // hackRegexHash.put("number","^(\\d+)($|\\s)");
        // hackRegexHash.put("word","^([A-Za-z]+)($|\\s)");

        try {
            JSONArray typesarray = new JSONArray(types);

            int arrlength = typesarray.length();
            for (int i = 0; i < arrlength; i++) {
                try {
                    JSONObject obj = typesarray.getJSONObject(i);
                    Log.d("dimagi", "type loop: " + i + " model: " + obj.getString("model"));
                    if (!obj.getString("model").equals("rapidandroid.fieldtype")) {
                        // System.out.println(obj.get("model"));
                        Log.d("dimagi", "###" + obj.getString("model") + "###");
                        assertTrue(false);
                    }

                    int pk = obj.getInt("pk");
                    JSONObject jsonfields = obj.getJSONObject("fields");
                    // Log.d("dimagi", "#### Parsing SimpleFieldType: " +
                    // jsonfields.getString("name") + " [" +
                    // hackRegexHash.get(jsonfields.getString("name")) + "]");
                    Log.d("dimagi", "#### Regex from file: " + jsonfields.getString("name") + " ["
                            + jsonfields.getString("regex") + "]");
                    // SimpleFieldType newtype = new SimpleFieldType(pk,
                    // jsonfields.getString("datatype"),hackRegexHash.get(jsonfields.getString("name")),jsonfields.getString("name"));
                    SimpleFieldType newtype = new SimpleFieldType(pk, jsonfields.getString("datatype"),
                            jsonfields.getString("regex"), jsonfields.getString("name"));
                    typeHash.put(Integer.valueOf(pk), newtype);

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    // Log.d("testBootstrapForms.typesinner", e.getMessage());
                    assertTrue(false);
                }
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block

            // Log.d("testBootstrapForms.typesouter", e.getMessage());
            assertTrue(false);
        }
    }

    private void insertFormsIntoDb(Vector<Form> forms) {
        // ok, now, let's create all the content types and such one by one.
        ModelTranslator.ClearFormTables();

        Log.d("dimagi", "** inserting forms into db");
        for (int i = 0; i < forms.size(); i++) {
            Form f = forms.get(i);
            Field[] fields = f.getFields();
            Log.d("dimagi", "**** inserting form " + f.getFormName());

            // insert the form first
            Uri formUri = Uri.parse(RapidSmsDBConstants.Form.CONTENT_URI_STRING + f.getFormId());
            Cursor crform = getContext().getContentResolver().query(formUri, null, null, null, null);
            if (crform.getCount() == 0) {
                ContentValues typecv = new ContentValues();

                typecv.put(RapidSmsDBConstants.Form._ID, f.getFormId());
                typecv.put(RapidSmsDBConstants.Form.FORMNAME, f.getFormName());
                // typecv.put(RapidSmsDBConstants.Form.PARSEMETHOD,
                // f.getParser().getName());
                typecv.put(RapidSmsDBConstants.Form.PARSEMETHOD, "simpleregex");
                typecv.put(RapidSmsDBConstants.Form.PREFIX, f.getPrefix());
                typecv.put(RapidSmsDBConstants.Form.DESCRIPTION, f.getDescription());

                Uri insertedFormUri = getContext().getContentResolver().insert(RapidSmsDBConstants.Form.CONTENT_URI,
                        typecv);
                Log.d("dimagi", "****** Inserted form into db: " + insertedFormUri);
                assertEquals(insertedFormUri.getPathSegments().get(1), f.getFormId() + "");
            }
            crform.close();

            Log.d("dimagi", "****** Begin fields loop: " + fields.length);
            for (int j = 0; j < fields.length; j++) {
                Field thefield = fields[j];
                SimpleFieldType thetype = (SimpleFieldType) thefield.getFieldType();
                // make the URI and insert for the Fieldtype
                Log.d("dimagi", "******** Iterating through fields: " + thefield.getName() + " id: "
                        + thefield.getFieldId());

                Uri fieldtypeUri = Uri.parse(RapidSmsDBConstants.FieldType.CONTENT_URI_STRING + thetype.getId());
                Cursor typeCursor = getContext().getContentResolver().query(fieldtypeUri, null, null, null, null);
                if (typeCursor.getCount() == 0) {
                    ContentValues typecv = new ContentValues();

                    typecv.put(RapidSmsDBConstants.FieldType._ID, thetype.getId());
                    typecv.put(RapidSmsDBConstants.FieldType.DATATYPE, thetype.getDataType());
                    typecv.put(RapidSmsDBConstants.FieldType.NAME, thetype.getReadableName());
                    typecv.put(RapidSmsDBConstants.FieldType.REGEX, thetype.getRegex());

                    Log.d("dimagi", "InsertFieldType: " + thetype.getId());
                    Log.d("dimagi", "InsertFieldType: " + thetype.getDataType());
                    Log.d("dimagi", "InsertFieldType: " + thetype.getReadableName());
                    Log.d("dimagi", "InsertFieldType: " + thetype.getRegex());

                    Uri insertedTypeUri = getContext().getContentResolver()
                            .insert(RapidSmsDBConstants.FieldType.CONTENT_URI, typecv);
                    Log.d("dimagi", "********** Inserted SimpleFieldType into db: " + insertedTypeUri);
                    assertEquals(insertedTypeUri.getPathSegments().get(1), thetype.getId() + "");
                }
                typeCursor.close();

                Uri fieldUri = Uri.parse(RapidSmsDBConstants.Field.CONTENT_URI_STRING + thefield.getFieldId());
                Cursor crfield = getContext().getContentResolver().query(fieldUri, null, null, null, null);
                if (crfield.getCount() == 0) {
                    ContentValues typecv = new ContentValues();

                    typecv.put(RapidSmsDBConstants.Field._ID, thefield.getFieldId());
                    typecv.put(RapidSmsDBConstants.Field.NAME, thefield.getName());
                    typecv.put(RapidSmsDBConstants.Field.FORM, f.getFormId());
                    typecv.put(RapidSmsDBConstants.Field.PROMPT, thefield.getDescription());
                    typecv.put(RapidSmsDBConstants.Field.SEQUENCE, thefield.getSequenceId());

                    typecv.put(RapidSmsDBConstants.Field.FIELDTYPE,
                            ((SimpleFieldType) (thefield.getFieldType())).getId());
                    // typecv.put(RapidSmsDBConstants.Field.FIELDTYPE,
                    // thefield.getFieldType().getId());

                    // Log.d("dimagi", "_ID: " + thefield.getFieldId());
                    // Log.d("dimagi", "NAME: " + thefield.getName());
                    // Log.d("dimagi", "FORM: " + f.getFormId());
                    // Log.d("dimagi", "PROMPT: " + thefield.getPrompt());
                    // Log.d("dimagi", "SEQUENCE: " + thefield.getSequenceId());
                    // Log.d("dimagi", "FIELDTYPE: " +
                    // thefield.getFieldType().getId());

                    Uri insertedFieldUri = getContext().getContentResolver()
                            .insert(RapidSmsDBConstants.Field.CONTENT_URI, typecv);
                    Log.d("dimagi", "********** Inserted Field into db: " + insertedFieldUri);
                    assertEquals(insertedFieldUri.getPathSegments().get(1), thefield.getFieldId() + "");
                }
                crfield.close();
                // next, make the uri and insert for the field.
            }
        }
        assertEquals(2, forms.size());
        Log.d("dimagi", "Test form insert success");

    }

    public void test006InsertDummyFormData() {

        test005RegenerateTablesForForms();

        Uri query = RapidSmsDBConstants.Form.CONTENT_URI;
        Cursor cr = getContext().getContentResolver().query(query, null, null, null, null);
        cr.moveToFirst();

        do {

            int id = cr.getInt(0); // presumably the id
            Uri directUri = Uri.parse(RapidSmsDBConstants.Form.CONTENT_URI_STRING + id);
            Form f = ModelTranslator.getFormFromUri(directUri);

            for (int msgcount = 0; msgcount < 10; msgcount++) {
                // first, let's make a new dummy message:

                // doSendMessage("test message " + msgcount, "10/31/2008 11:0"
                // + msgcount, "6176453236");
                // String msgid = currUri.getPathSegments().get(1);
                String msgid = "1";

                ContentValues cv = new ContentValues();
                cv.put(RapidSmsDBConstants.FormData.MESSAGE, msgid);
                Field[] fields = f.getFields();
                int len = fields.length;
                Random r = new Random();

                for (int i = 0; i < len; i++) {
                    Field field = fields[i];
                    if (field.getFieldType().getParsedDataType().equals("integer")) {
                        cv.put(RapidSmsDBConstants.FormData.COLUMN_PREFIX + field.getName(), r.nextInt(10000));
                    } else if (field.getFieldType().getParsedDataType().equals("number")) {
                        cv.put(RapidSmsDBConstants.FormData.COLUMN_PREFIX + field.getName(), r.nextInt(10000));
                    } else if (field.getFieldType().getParsedDataType().equals("boolean")) {
                        cv.put(RapidSmsDBConstants.FormData.COLUMN_PREFIX + field.getName(), r.nextBoolean());
                    } else if (field.getFieldType().getParsedDataType().equals("word")) {
                        cv.put(RapidSmsDBConstants.FormData.COLUMN_PREFIX + field.getName(), Math.random() + "");
                    } else if (field.getFieldType().getParsedDataType().equals("ratio")) {
                        cv.put(RapidSmsDBConstants.FormData.COLUMN_PREFIX + field.getName(), Math.random() + "");
                    } else if (field.getFieldType().getParsedDataType().equals("datetime")) {
                        cv.put(RapidSmsDBConstants.FormData.COLUMN_PREFIX + field.getName(), "10/31/2008 11:59");
                    }
                }
                Uri inserted = getContext().getContentResolver()
                        .insert(Uri.parse(RapidSmsDBConstants.FormData.CONTENT_URI_PREFIX + f.getFormId()), cv);
                Log.d("dimagi", "inserted form data for: " + inserted);
            }

        } while (cr.moveToNext());
        cr.close();
    }
}