aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/persistance
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/persistance')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java203
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java60
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java46
3 files changed, 309 insertions, 0 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java b/src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java
new file mode 100644
index 00000000..7e3fdab0
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/CursorHelper.java
@@ -0,0 +1,203 @@
+package de.thedevstack.conversationsplus.persistance;
+
+import android.database.Cursor;
+
+/**
+ * Created by steckbrief on 15.04.2016.
+ */
+public abstract class CursorHelper {
+
+ static double getDouble(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Double.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Double.MIN_VALUE;
+ }
+ return getDouble(cursor, columnIndex);
+ }
+
+ static String getString(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return null;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return null;
+ }
+ return getString(cursor, columnIndex);
+ }
+
+ static float getFloat(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Float.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Float.MIN_VALUE;
+ }
+ return getFloat(cursor, columnIndex);
+ }
+
+ static int getInt(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Integer.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Integer.MIN_VALUE;
+ }
+ return getInt(cursor, columnIndex);
+ }
+
+ static long getLong(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Long.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Long.MIN_VALUE;
+ }
+ return getLong(cursor, columnIndex);
+ }
+
+ static int getShort(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return Short.MIN_VALUE;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return Short.MIN_VALUE;
+ }
+ return getShort(cursor, columnIndex);
+ }
+
+ static byte[] getBlob(Cursor cursor, String columnName) {
+ if (null == cursor) {
+ return null;
+ }
+ int columnIndex = getColumnIndex(cursor, columnName);
+ if (columnIndex < 0) {
+ return null;
+ }
+ return getBlob(cursor, columnIndex);
+ }
+
+ /**
+ * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
+ * If you expect the column to exist use {@link Cursor#getColumnIndexOrThrow(String)} instead, which
+ * will make the error more clear.
+ *
+ * @param columnName the name of the target column.
+ * @return the zero-based column index for the given column name, or -1 if
+ * the column name does not exist.
+ * @see Cursor#getColumnIndexOrThrow(String)
+ */
+ static int getColumnIndex(Cursor cursor, String columnName) {
+ return cursor.getColumnIndex(columnName);
+ }
+
+ /**
+ * Returns the value of the requested column as a byte array.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null or the column type is not a blob type is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a byte array.
+ */
+ static byte[] getBlob(Cursor cursor, int columnIndex) {
+ return cursor.getBlob(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a String.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null or the column type is not a string type is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a String.
+ */
+ static String getString(Cursor cursor, int columnIndex) {
+ return cursor.getString(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a short.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not an integral type, or the
+ * integer value is outside the range [<code>Short.MIN_VALUE</code>,
+ * <code>Short.MAX_VALUE</code>] is implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a short.
+ */
+ static short getShort(Cursor cursor, int columnIndex) {
+ return cursor.getShort(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as an int.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not an integral type, or the
+ * integer value is outside the range [<code>Integer.MIN_VALUE</code>,
+ * <code>Integer.MAX_VALUE</code>] is implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as an int.
+ */
+ static int getInt(Cursor cursor, int columnIndex) {
+ return cursor.getInt(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a long.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not an integral type, or the
+ * integer value is outside the range [<code>Long.MIN_VALUE</code>,
+ * <code>Long.MAX_VALUE</code>] is implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a long.
+ */
+ static long getLong(Cursor cursor, int columnIndex) {
+ return cursor.getLong(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a float.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not a floating-point type, or the
+ * floating-point value is not representable as a <code>float</code> value is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a float.
+ */
+ static float getFloat(Cursor cursor, int columnIndex) {
+ return cursor.getFloat(columnIndex);
+ }
+
+ /**
+ * Returns the value of the requested column as a double.
+ *
+ * <p>The result and whether this method throws an exception when the
+ * column value is null, the column type is not a floating-point type, or the
+ * floating-point value is not representable as a <code>double</code> value is
+ * implementation-defined.
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return the value of that column as a double.
+ */
+ static double getDouble(Cursor cursor, int columnIndex) {
+ return cursor.getDouble(columnIndex);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java b/src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java
new file mode 100644
index 00000000..ba5f4a2c
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/MessageDatabaseAccess.java
@@ -0,0 +1,60 @@
+package de.thedevstack.conversationsplus.persistance;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import de.thedevstack.android.logcat.Logging;
+
+import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.xmpp.jid.InvalidJidException;
+import eu.siacs.conversations.xmpp.jid.Jid;
+
+/**
+ * Created by steckbrief on 15.04.2016.
+ */
+public class MessageDatabaseAccess {
+ public static final String TABLE_NAME_ADDITIONAL_PARAMETERS = "message_parameters";
+ public static final String COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD = "httpupload";
+ public static final String COLUMN_NAME_MSG_PARAMS_MSGUUID = "message_uuid";
+ public static final String COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION = "treatasdownloadable_decision";
+
+ public static final String TABLE_ADDITIONAL_PARAMETERS_CREATE_V0 = "CREATE TABLE " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + " ("
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + " TEXT, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD + " INTEGER DEFAULT 0, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION + " TEXT DEFAULT 'NOT_DECIDED', "
+ + "FOREIGN KEY(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") REFERENCES " + Message.TABLENAME + "(" + Message.UUID + ") ON DELETE CASCADE)";
+
+ public static ContentValues getAdditionalParametersContentValues(Message message) {
+ ContentValues additionalParameters = new ContentValues();
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID, message.getUuid());
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD, message.isHttpUploaded() ? 1 : 0);
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION, message.treatAsDownloadable().name());
+
+ return additionalParameters;
+ }
+
+ public static void populateMessageParametersFromCursor(Cursor cursor, Message message) {
+ boolean isHttpUploaded = CursorHelper.getInt(cursor, COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD) == 1;
+ message.setHttpUploaded(isHttpUploaded);
+ String downloadable = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION);
+ Message.Decision treatAsDownloadable = Message.Decision.NOT_DECIDED;
+ try {
+ treatAsDownloadable = Message.Decision.valueOf(downloadable);
+ } catch (IllegalArgumentException e) {
+ // Should only happen if the database is corrupted, but to be on the save side catch it here
+ Logging.e("db.msg", "Unknown Decision for treatAsDownloadable found: '" + downloadable + "'");
+ }
+ message.setTreatAsDownloadable(treatAsDownloadable);
+ }
+
+ public static void populateMessageParameters(SQLiteDatabase db, Message message) {
+ Cursor paramsCursor = db.query(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS,
+ null, MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?",
+ new String[] {message.getUuid()},
+ null, null, null, null);
+ paramsCursor.moveToNext();
+ MessageDatabaseAccess.populateMessageParametersFromCursor(paramsCursor, message);
+ paramsCursor.close();
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java b/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java
new file mode 100644
index 00000000..a313c8b1
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java
@@ -0,0 +1,46 @@
+package de.thedevstack.conversationsplus.persistance.observers;
+
+import android.os.FileObserver;
+
+import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
+import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor;
+
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.entities.Transferable;
+import eu.siacs.conversations.entities.TransferablePlaceholder;
+
+/**
+ * Observer to mark messages containing files which are deleted.
+ */
+public class FileDeletionObserver extends FileObserver {
+ public FileDeletionObserver(String path) {
+ super(path, FileObserver.DELETE);
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ if (null != path) {
+ markFileDeleted(path.split("\\.")[0]);
+ }
+ }
+
+ private void markFileDeleted(String uuid) {
+ if (null != XmppConnectionServiceAccessor.xmppConnectionService) {
+ for (Conversation conversation : XmppConnectionServiceAccessor.xmppConnectionService.getConversations()) {
+ Message message = conversation.findMessageWithFileAndUuid(uuid);
+ if (message != null) {
+ message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
+ final int s = message.getStatus();
+ if (s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) {
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
+ } else {
+ UiUpdateHelper.updateConversationUi();
+ }
+ return;
+ }
+ }
+ }
+ }
+}