/* * RapidPro Android Channel - Relay SMS messages where MNO connections aren't practical. * Copyright (C) 2014 Nyaruka, UNICEF * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package io.rapidpro.androidchannel.payload; import android.content.Context; import android.database.Cursor; import io.rapidpro.androidchannel.data.DBCommandHelper; import io.rapidpro.androidchannel.json.JSON; public abstract class Command { public static final String COMMAND = "cmd"; public static final String PAYLOAD_ID = "p_id"; public static final String PHONE = "phone"; public static final String MESSAGE_ID = "msg_id"; public static final String MESSAGE = "msg"; public static final String LOCAL_MESSAGE_ID = "loc_id"; public static final String DATE = "ts"; public static final String RECEIVED = "ts"; public static final String SENT = "ts"; public static final String DELIVERED = "ts"; public static final String FAILED = "ts"; public static final String EXTRA = "extra"; /** our command name */ private String m_command; /** our id in our command database */ private long m_commandId; /** the id in the payload */ private int m_payloadId; /** when this command was created */ private long m_created; /** when the command was last modified */ private long m_modified; /** The extra on this command */ private String m_extra; public Command(String command){ m_command = command; m_created = System.currentTimeMillis(); m_modified = System.currentTimeMillis(); } public String getCommand(){ return m_command; } public int getPayloadId(){ return m_payloadId; } public void setPayloadId(int id){ m_payloadId = id; } public long getCommandId(){ return m_commandId; } public void setCommandId(long id){ m_commandId = id; } public void setDates(long created, long modified) { m_created = created; m_modified = modified; } public long getCreated() { return m_created; } public long getModified() { return m_modified; } public void setExtra(String extra){ m_extra = extra; } public String getExtra(){ return m_extra; } /** * Executes this command. * * @param context Our local context * @param sent The payload that was m_sent to the server */ public void execute(Context context, SyncPayload sent){ throw new RuntimeException("Execute not supported on this command type: " + getCommand()); } /** * Called when a command has been acknowledged by the server. * * @param ack The Ack as m_sent by the server */ public void ack(Context context, Ack ack){ throw new RuntimeException("Ack not supported on this command type: " + getCommand()); } /** * Factory for commands given a JSON blob. Throws an exception * if the passed in command is not recognized as something we know. * * @param json * @return */ public static Command fromJSON(JSON json){ String type = json.getString(COMMAND); Command cmd; if (type.equals(MTBroadcast.CMD)){ cmd = new MTBroadcast(json); } else if (type.equals(RegistrationCommand.CMD)){ cmd = new RegistrationCommand(json); } else if (type.equals(MOTextMessage.CMD)) { cmd = new MOTextMessage(json); } else if (type.equals(Ack.CMD)) { cmd = new Ack(json); } else if (type.equals(MTTextSent.CMD)){ cmd = new MTTextSent(json); } else if (type.equals(ReleaseCommand.CMD)) { cmd = new ReleaseCommand(json); } else if (type.equals(MTTextFailed.CMD)){ cmd = new MTTextFailed(json); } else if (type.equals(ClaimCommand.CMD)) { cmd = new ClaimCommand(json); } else if (type.equals(ResetCommand.CMD)){ cmd = new ResetCommand(json); } else { throw new RuntimeException("Unknown command: " + json.toString()); } return cmd; } /** * Factory for commands given a JSON blob. Throws an exception * if the passed in command is not recognized as something we know. * * @param cursor The cursor to build our command off of * @return */ public static Command fromCursor(Cursor cursor){ JSON json = new JSON(cursor.getString(DBCommandHelper.BLOB_IDX)); String type = cursor.getString(DBCommandHelper.CMD_IDX); Command cmd; if (type.equals(MTBroadcast.CMD)){ cmd = new MTBroadcast(json); } else if (type.equals(RegistrationCommand.CMD)){ cmd = new RegistrationCommand(json); } else if (type.equals(MOTextMessage.CMD)) { cmd = new MOTextMessage(json); } else if (type.equals(Ack.CMD)) { cmd = new Ack(json); } else if (type.equals(MTTextMessage.CMD)){ cmd = new MTTextMessage(json); } else if (type.equals(MTTextSent.CMD)){ cmd = new MTTextSent(json); } else if (type.equals(MTTextDelivered.CMD)){ cmd = new MTTextDelivered(json); } else if (type.equals(MTTextFailed.CMD)){ cmd = new MTTextFailed(json); } else if (type.equals(CallLog.CMD)){ cmd = new CallLog(json); } else if (type.equals(ResetCommand.CMD)){ cmd = new ResetCommand(json); } else { throw new RuntimeException("Unknown command: " + json.toString()); } // set our db id for this command cmd.setCommandId(cursor.getInt(DBCommandHelper.ID_IDX)); cmd.setDates(cursor.getLong(DBCommandHelper.CREATED_IDX), cursor.getLong(DBCommandHelper.MODIFIED_IDX)); cmd.setExtra(cursor.getString(DBCommandHelper.EXTRA_IDX)); return cmd; } public abstract JSON asJSON(); public String toString(){ return getCommand(); } }