/* * 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. * */ package org.rapidandroid.content.translation; import java.util.Date; import java.util.HashMap; import org.rapidandroid.data.RapidSmsDBConstants; import org.rapidsms.java.core.model.Message; import org.rapidsms.java.core.model.Monitor; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; /** * Helper class to simplify the insertion and querying of raw SMS messages from * the content provider. * * <br> * Goal for this class is to return Message objects instead of cursors. * * @author Daniel Myung dmyung@dimagi.com * @created Jan 21, 2009 * * */ public class MessageTranslator { private static HashMap<Integer, Monitor> mMonitorHash = new HashMap<Integer, Monitor>(); private static HashMap<String, Monitor> mMonitorHashByPhone = new HashMap<String, Monitor>(); /** * To ease DB hits on the insert of messages, the monitorhash has two * hastables indexed by phone number and ID. We need to update this thing on * each new insert. * * @param context */ public static synchronized void updateMonitorHash(Context context) { mMonitorHash = new HashMap<Integer, Monitor>(); mMonitorHashByPhone = new HashMap<String, Monitor>(); Cursor monitorCursor = context.getContentResolver().query(RapidSmsDBConstants.Monitor.CONTENT_URI, null, null, null, null); // if (monitorCursor.getCount() == 0) { // monitorCursor.close(); // return; // } if (monitorCursor.moveToFirst()) { do { // (int id, String firstName, String lastName, String alias, // String phone, String email, int incomingMessages) { Monitor newMonitor = new Monitor(monitorCursor.getInt(Monitor.COL_ID), monitorCursor.getString(Monitor.COL_FIRSTNAME), monitorCursor.getString(Monitor.COL_LASTNAME), monitorCursor.getString(Monitor.COL_ALIAS), monitorCursor.getString(Monitor.COL_PHONE), monitorCursor.getString(Monitor.COL_EMAIL), monitorCursor.getInt(Monitor.COL_MESSAGECOUNT), monitorCursor.getInt(Monitor.COL_RECEIVE_REPLY) == 1); mMonitorHash.put(Integer.valueOf(newMonitor.getID()), newMonitor); mMonitorHashByPhone.put(newMonitor.getPhone(), newMonitor); } while (monitorCursor.moveToNext()); } monitorCursor.close(); } /** * Get a handle to monitor for a given ID * * @param context * @param monitorID * @return */ public static synchronized Monitor GetMonitor(Context context, int monitorID) { Integer monID = Integer.valueOf(monitorID); if (mMonitorHash.containsKey(monID)) { return mMonitorHash.get(monID); } else { throw new IllegalArgumentException( "Error in application state. The monitor hash should always be up to date when querying"); } } /** * Get a monitor or insert a new one based upon a given phone number * * @returns The monitor found or created. This is necesary to do link a new * message to a Monitor.ID * */ public static synchronized Monitor GetMonitorAndInsertIfNew(Context context, String phone) { if (mMonitorHashByPhone.containsKey(phone)) { return mMonitorHashByPhone.get(phone); } else { ContentValues cv = new ContentValues(); cv.put(RapidSmsDBConstants.Monitor.PHONE, phone); Uri newUri = context.getContentResolver().insert(RapidSmsDBConstants.Monitor.CONTENT_URI, cv); // updateMonitorHash(context); return mMonitorHashByPhone.get(phone); } } public static synchronized Message GetMessage(Context context, int messageID) { if (mMonitorHash == null) { updateMonitorHash(context); } Uri getMessageUri = Uri.parse(RapidSmsDBConstants.Message.CONTENT_URI_STRING + messageID); Cursor msgCursor = context.getContentResolver().query(getMessageUri, null, null, null, null); msgCursor.moveToFirst(); if (msgCursor.getCount() != 1) { msgCursor.close(); return null; } else { try { String datestring = msgCursor.getString(Message.COL_TIME); Date msgDate = Message.SQLDateFormatter.parse(datestring); String recvstring = msgCursor.getString(Message.COL_RECEIVE_TIME); Date recvDate = msgDate; // for old entries, should we set it to // null or just copy it? if (recvstring == null || recvstring == "") { recvDate = Message.SQLDateFormatter.parse(datestring); } Message newMessage = new Message( msgCursor.getInt(Message.COL_ID), msgCursor.getString(Message.COL_MESSAGE), msgDate, mMonitorHash .get(Integer .valueOf(msgCursor .getInt(Message.COL_MONITOR))), recvDate); msgCursor.close(); return newMessage; } catch (Exception ex) { throw new IllegalArgumentException("Invalid state"); } } } public static synchronized Message[] GetMessages(Context context, int[] messages) { if (mMonitorHash == null) { updateMonitorHash(context); } Uri getMessageUri = RapidSmsDBConstants.Message.CONTENT_URI; String whereclause = "_id in ("; int length = messages.length; for (int i = 0; i < length; i++) { whereclause += messages[i]; if (i < length - 1) { whereclause += ","; } } whereclause += ")"; Cursor msgCursor = context.getContentResolver().query(getMessageUri, null, whereclause, null, "time DESC"); int retlen = msgCursor.getCount(); Message[] ret = new Message[retlen]; msgCursor.moveToFirst(); for (int i = 0; i < retlen; i++) { try { String datestring = msgCursor.getString(Message.COL_TIME); Date msgDate = Message.SQLDateFormatter.parse(datestring); String recvstring = msgCursor.getString(Message.COL_RECEIVE_TIME); Date recvDate = msgDate; // for old entries, should we set it to // null or just copy it? if (recvstring == null || recvstring == "") { recvDate = Message.SQLDateFormatter.parse(datestring); } Message newMessage = new Message( msgCursor.getInt(Message.COL_ID), msgCursor.getString(Message.COL_MESSAGE), msgDate, mMonitorHash .get(Integer .valueOf(msgCursor .getInt(Message.COL_MONITOR))), recvDate); ret[i] = newMessage; } catch (Exception ex) { // unable to parse datetime format } msgCursor.moveToNext(); } msgCursor.close(); return ret; } }