From b469f6de9578a6d86c8b92c5671b9b8050332cf0 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 19 May 2019 02:00:33 +0200 Subject: [PATCH] Hacked Roster loading --- .idea/assetWizardSettings.xml | 14 -- .idea/gradle.xml | 4 + .idea/misc.xml | 47 +----- .idea/vcs.xml | 2 +- app/build.gradle | 30 +--- .../messenger/di/module/RepositoryModule.java | 16 +- .../messenger/di/module/RoomModule.java | 13 +- .../persistence/database/dao/AccountDao.java | 52 ------- .../database/dao/RosterEntryDao.java | 40 ----- .../repository/account/AccountRepository.java | 16 -- .../roster/RosterEntryRepository.java | 19 --- .../roster/RosterEntryRepositoryImpl.java | 24 --- .../service/MessengerXmppConnection.java | 6 +- .../messenger/service/XmppService.java | 139 +++++++++++------- .../mercury_im/messenger/ui/MainActivity.java | 24 +-- .../messenger/ui/chat/ChatViewModel.java | 6 +- .../messenger/ui/login/LoginActivity.java | 6 +- .../messenger/ui/login/LoginViewModel.java | 14 +- .../messenger/ui/roster/RosterFragment.java | 6 +- .../ui/roster/RosterRecyclerViewAdapter.java | 10 +- .../messenger/ui/roster/RosterViewModel.java | 8 +- persistence-room/.gitignore | 1 + persistence-room/build.gradle | 43 ++++++ persistence-room/proguard-rules.pro | 21 +++ .../room/ExampleInstrumentedTest.java | 27 ++++ persistence-room/src/main/AndroidManifest.xml | 2 + .../persistence/room}/AppDatabase.java | 16 +- .../persistence/room/dao/AccountDao.java | 44 ++++++ .../persistence/room/dao/BaseDao.java | 17 +++ .../persistence/room/dao/MessageDao.java | 24 +++ .../persistence/room/dao/RosterEntryDao.java | 35 +++++ .../room/model/RoomAccountModel.java | 19 ++- .../room/model/RoomMessageModel.java | 101 +++++++++++++ .../room/model/RoomRosterEntryModel.java | 37 +++-- .../room/repository/IAccountRepository.java | 32 ++-- .../room/repository/IMessageRepository.java | 7 + .../repository/IRosterEntryRepository.java | 31 ++++ .../type_converter/BareJidConverter.java | 2 +- .../room/type_converter/DateConverter.java | 18 +++ .../EntityBareJidConverter.java | 2 +- .../EntityFullJidConverter.java | 25 ++++ .../src/main/res/values/strings.xml | 3 + .../persistence/room/ExampleUnitTest.java | 17 +++ persistence/.gitignore | 1 + persistence/build.gradle | 40 +++++ persistence/proguard-rules.pro | 21 +++ .../persistence/ExampleInstrumentedTest.java | 27 ++++ persistence/src/main/AndroidManifest.xml | 2 + .../persistence/model/AccountModel.java | 8 +- .../persistence/model/MessageModel.java | 32 ++++ .../persistence/model/RosterEntryModel.java | 24 +++ .../repository/AccountRepository.java | 16 ++ .../repository/MessageRepository.java | 7 + .../repository/RosterEntryRepository.java | 14 ++ persistence/src/main/res/values/strings.xml | 3 + .../persistence/ExampleUnitTest.java | 17 +++ settings.gradle | 2 +- xmpp_core/.gitignore | 1 + xmpp_core/build.gradle | 26 ++++ .../xmpp_core/MercuryConnection.java | 16 ++ 60 files changed, 898 insertions(+), 379 deletions(-) delete mode 100644 .idea/assetWizardSettings.xml delete mode 100644 app/src/main/java/org/mercury_im/messenger/persistence/database/dao/AccountDao.java delete mode 100644 app/src/main/java/org/mercury_im/messenger/persistence/database/dao/RosterEntryDao.java delete mode 100644 app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepository.java delete mode 100644 app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepository.java delete mode 100644 app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepositoryImpl.java create mode 100644 persistence-room/.gitignore create mode 100644 persistence-room/build.gradle create mode 100644 persistence-room/proguard-rules.pro create mode 100644 persistence-room/src/androidTest/java/org/mercury_im/messenger/persistence/room/ExampleInstrumentedTest.java create mode 100644 persistence-room/src/main/AndroidManifest.xml rename {app/src/main/java/org/mercury_im/messenger/persistence/database => persistence-room/src/main/java/org/mercury_im/messenger/persistence/room}/AppDatabase.java (52%) create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/AccountDao.java create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/BaseDao.java create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/MessageDao.java create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/RosterEntryDao.java rename app/src/main/java/org/mercury_im/messenger/persistence/database/model/AccountModel.java => persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomAccountModel.java (70%) create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomMessageModel.java rename app/src/main/java/org/mercury_im/messenger/persistence/database/model/RosterEntryModel.java => persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomRosterEntryModel.java (58%) rename app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepositoryImpl.java => persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IAccountRepository.java (56%) create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IMessageRepository.java create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IRosterEntryRepository.java rename {app/src/main/java/org/mercury_im/messenger/persistence/database => persistence-room/src/main/java/org/mercury_im/messenger/persistence/room}/type_converter/BareJidConverter.java (89%) create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/DateConverter.java rename {app/src/main/java/org/mercury_im/messenger/persistence/database => persistence-room/src/main/java/org/mercury_im/messenger/persistence/room}/type_converter/EntityBareJidConverter.java (90%) create mode 100644 persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityFullJidConverter.java create mode 100644 persistence-room/src/main/res/values/strings.xml create mode 100644 persistence-room/src/test/java/org/mercury_im/messenger/persistence/room/ExampleUnitTest.java create mode 100644 persistence/.gitignore create mode 100644 persistence/build.gradle create mode 100644 persistence/proguard-rules.pro create mode 100644 persistence/src/androidTest/java/org/mercury_im/messenger/persistence/ExampleInstrumentedTest.java create mode 100644 persistence/src/main/AndroidManifest.xml rename app/src/main/java/org/mercury_im/messenger/persistence/database/model/Account.java => persistence/src/main/java/org/mercury_im/messenger/persistence/model/AccountModel.java (64%) create mode 100644 persistence/src/main/java/org/mercury_im/messenger/persistence/model/MessageModel.java create mode 100644 persistence/src/main/java/org/mercury_im/messenger/persistence/model/RosterEntryModel.java create mode 100644 persistence/src/main/java/org/mercury_im/messenger/persistence/repository/AccountRepository.java create mode 100644 persistence/src/main/java/org/mercury_im/messenger/persistence/repository/MessageRepository.java create mode 100644 persistence/src/main/java/org/mercury_im/messenger/persistence/repository/RosterEntryRepository.java create mode 100644 persistence/src/main/res/values/strings.xml create mode 100644 persistence/src/test/java/org/mercury_im/messenger/persistence/ExampleUnitTest.java create mode 100644 xmpp_core/.gitignore create mode 100644 xmpp_core/build.gradle create mode 100644 xmpp_core/src/main/java/org/mercury_im/xmpp_core/MercuryConnection.java diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml deleted file mode 100644 index 6b96cf0..0000000 --- a/.idea/assetWizardSettings.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index f43d428..ac07efe 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -12,9 +12,13 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index 422a406..84da703 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,49 +1,6 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1dd..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c3f343c..d67808a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,6 +71,12 @@ check.configure { // Dependency versions are located in version.gradle dependencies { + + implementation project(":xmpp_core") + implementation(project(':persistence-room')) { + transitive = true + } + /* architecture components for database and lifecycle management */ @@ -79,10 +85,6 @@ dependencies { implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion" annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycleVersion" - // Room - implementation "androidx.room:room-runtime:$roomVersion" - annotationProcessor "androidx.room:room-compiler:$roomVersion" - // Dagger 2 for dependency injection implementation "com.google.dagger:dagger:$daggerVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" @@ -101,24 +103,4 @@ dependencies { // circular image viewer for avatars implementation 'de.hdodenhof:circleimageview:2.2.0' - - // Smack - // Not all of those are needed, but it may be a good idea to define those versions explicitly - implementation "org.igniterealtime.smack:smack-android:$smackAndroidVersion" - implementation "org.igniterealtime.smack:smack-android-extensions:$smackAndroidExtensionsVersion" - implementation "org.igniterealtime.smack:smack-core:$smackCoreVersion" - implementation "org.igniterealtime.smack:smack-experimental:$smackExperimentalVersion" - implementation "org.igniterealtime.smack:smack-extensions:$smackExtensionsVersion" - implementation "org.igniterealtime.smack:smack-im:$smackImVersion" - implementation "org.igniterealtime.smack:smack-omemo:$smackOmemoVersion" - implementation "org.igniterealtime.smack:smack-omemo-signal:$smackOmemoSignalVersion" - implementation "org.igniterealtime.smack:smack-openpgp:$smackOpenPGPVersion" - implementation "org.igniterealtime.smack:smack-resolver-minidns:$smackResolverMiniDnsVersion" - implementation "org.igniterealtime.smack:smack-tcp:$smackTcpVersion" - - // Exclude XmlPullParser from Smack dependencies, as its now provided by Android - // https://stackoverflow.com/questions/48488563/gradle-xpp3-error/48746294#48746294 - configurations { - all*.exclude group: 'xpp3', module: 'xpp3' - } } diff --git a/app/src/main/java/org/mercury_im/messenger/di/module/RepositoryModule.java b/app/src/main/java/org/mercury_im/messenger/di/module/RepositoryModule.java index 4ed28df..cc05b52 100644 --- a/app/src/main/java/org/mercury_im/messenger/di/module/RepositoryModule.java +++ b/app/src/main/java/org/mercury_im/messenger/di/module/RepositoryModule.java @@ -1,11 +1,11 @@ package org.mercury_im.messenger.di.module; -import org.mercury_im.messenger.persistence.database.dao.AccountDao; -import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao; -import org.mercury_im.messenger.persistence.repository.account.AccountRepository; -import org.mercury_im.messenger.persistence.repository.account.AccountRepositoryImpl; -import org.mercury_im.messenger.persistence.repository.roster.RosterEntryRepository; -import org.mercury_im.messenger.persistence.repository.roster.RosterEntryRepositoryImpl; +import org.mercury_im.messenger.persistence.repository.AccountRepository; +import org.mercury_im.messenger.persistence.repository.RosterEntryRepository; +import org.mercury_im.messenger.persistence.room.dao.AccountDao; +import org.mercury_im.messenger.persistence.room.dao.RosterEntryDao; +import org.mercury_im.messenger.persistence.room.repository.IAccountRepository; +import org.mercury_im.messenger.persistence.room.repository.IRosterEntryRepository; import javax.inject.Singleton; @@ -18,12 +18,12 @@ public class RepositoryModule { @Singleton @Provides AccountRepository provideAccountRepository(AccountDao dao) { - return new AccountRepositoryImpl(dao); + return new IAccountRepository(dao); } @Singleton @Provides RosterEntryRepository provideRosterEntryRepository(RosterEntryDao dao) { - return new RosterEntryRepositoryImpl(dao); + return new IRosterEntryRepository(dao); } } diff --git a/app/src/main/java/org/mercury_im/messenger/di/module/RoomModule.java b/app/src/main/java/org/mercury_im/messenger/di/module/RoomModule.java index 0530bde..f3e40d8 100644 --- a/app/src/main/java/org/mercury_im/messenger/di/module/RoomModule.java +++ b/app/src/main/java/org/mercury_im/messenger/di/module/RoomModule.java @@ -1,9 +1,10 @@ package org.mercury_im.messenger.di.module; import org.mercury_im.messenger.MercuryImApplication; -import org.mercury_im.messenger.persistence.database.AppDatabase; -import org.mercury_im.messenger.persistence.database.dao.AccountDao; -import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao; +import org.mercury_im.messenger.persistence.room.AppDatabase; +import org.mercury_im.messenger.persistence.room.dao.AccountDao; +import org.mercury_im.messenger.persistence.room.dao.MessageDao; +import org.mercury_im.messenger.persistence.room.dao.RosterEntryDao; import javax.inject.Inject; import javax.inject.Singleton; @@ -41,4 +42,10 @@ public class RoomModule { RosterEntryDao provideRosterEntryDao() { return mAppDatabase.rosterEntryDao(); } + + @Singleton + @Provides + MessageDao provideMessageDao() { + return mAppDatabase.messageDao(); + } } diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/dao/AccountDao.java b/app/src/main/java/org/mercury_im/messenger/persistence/database/dao/AccountDao.java deleted file mode 100644 index 0cb9cc8..0000000 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/dao/AccountDao.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.mercury_im.messenger.persistence.database.dao; - -import androidx.lifecycle.LiveData; -import androidx.annotation.WorkerThread; -import androidx.room.Dao; -import androidx.room.Delete; -import androidx.room.Insert; -import androidx.room.Query; -import androidx.room.TypeConverters; -import androidx.room.Update; - -import org.jxmpp.jid.EntityBareJid; -import org.mercury_im.messenger.persistence.database.model.AccountModel; -import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; - -import java.util.List; - -@Dao -@TypeConverters(EntityBareJidConverter.class) -@WorkerThread -public interface AccountDao { - - /** - * Return a {@link LiveData} wrapping a {@link List} which contains all - * {@link AccountModel Accounts} which are currently stored in the database. - * - * @return live updating account list - */ - @Query("select * from AccountModel") - LiveData> getAllAccounts(); - - /** - * Return the {@link AccountModel Account} which is identified by the given id. - * - * @param id id of the account - * @return account or null - */ - @Query("select * from AccountModel where id = :id") - LiveData getAccountById(long id); - - @Query("select * from AccountModel where jid = :jid") - LiveData getAccountByJid(EntityBareJid jid); - - @Insert - long insertAccount(AccountModel account); - - @Update - void updateAccount(AccountModel account); - - @Delete - void deleteAccount(AccountModel account); -} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/dao/RosterEntryDao.java b/app/src/main/java/org/mercury_im/messenger/persistence/database/dao/RosterEntryDao.java deleted file mode 100644 index a056d00..0000000 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/dao/RosterEntryDao.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.mercury_im.messenger.persistence.database.dao; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Delete; -import androidx.room.Insert; -import androidx.room.Query; -import androidx.room.TypeConverters; - -import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; - -import java.util.List; - -import static androidx.room.OnConflictStrategy.REPLACE; - -@Dao -@TypeConverters(EntityBareJidConverter.class) -public interface RosterEntryDao { - - /** - * Return a {@link LiveData} wrapping a {@link List} of all {@link RosterEntryModel RosterEntries} - * which are currently found in the database. - * @return - */ - @Query("select * from RosterEntryModel") - LiveData> getAllRosterEntries(); - - @Query("select * from RosterEntryModel where id = :id") - RosterEntryModel getRosterEntryById(String id); - - @Query("select * from RosterEntryModel where accountId = :accountId") - LiveData> getRosterEntriesForAccount(String accountId); - - @Insert(onConflict = REPLACE) - void addRosterEntry(RosterEntryModel rosterEntry); - - @Delete - void deleteRosterEntry(RosterEntryModel rosterEntry); -} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepository.java b/app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepository.java deleted file mode 100644 index e3eadfc..0000000 --- a/app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mercury_im.messenger.persistence.repository.account; - -import androidx.lifecycle.LiveData; - -import org.mercury_im.messenger.persistence.database.model.AccountModel; - -import java.util.List; - -public interface AccountRepository { - - LiveData getAccount(long accountId); - - LiveData> getAllAccounts(); - - long insertAccount(AccountModel accountModel); -} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepository.java b/app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepository.java deleted file mode 100644 index 6cc0a65..0000000 --- a/app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.mercury_im.messenger.persistence.repository.roster; - -import androidx.lifecycle.LiveData; - -import org.jivesoftware.smack.roster.RosterEntry; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; -import org.mercury_im.messenger.ui.roster.RosterViewModel; - -import java.util.List; - -public interface RosterEntryRepository { - - /** - * Return a {@link LiveData} object of a {@link RosterViewModel} which contains - * {@link RosterEntryModel} for all {@link RosterEntry RosterEntries} in the users roster. - * @return - */ - LiveData> getAllRosterEntries(); -} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepositoryImpl.java b/app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepositoryImpl.java deleted file mode 100644 index 7f702c1..0000000 --- a/app/src/main/java/org/mercury_im/messenger/persistence/repository/roster/RosterEntryRepositoryImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.mercury_im.messenger.persistence.repository.roster; - -import androidx.lifecycle.LiveData; - -import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; - -import java.util.List; - -public class RosterEntryRepositoryImpl implements RosterEntryRepository { - - private final RosterEntryDao rosterEntryDao; - - public RosterEntryRepositoryImpl(RosterEntryDao dao) { - this.rosterEntryDao = dao; - } - - @Override - public LiveData> getAllRosterEntries() { - return rosterEntryDao.getAllRosterEntries(); - } - - -} diff --git a/app/src/main/java/org/mercury_im/messenger/service/MessengerXmppConnection.java b/app/src/main/java/org/mercury_im/messenger/service/MessengerXmppConnection.java index f0b2d4b..337933f 100644 --- a/app/src/main/java/org/mercury_im/messenger/service/MessengerXmppConnection.java +++ b/app/src/main/java/org/mercury_im/messenger/service/MessengerXmppConnection.java @@ -1,14 +1,14 @@ package org.mercury_im.messenger.service; import org.jivesoftware.smack.XMPPConnection; -import org.mercury_im.messenger.persistence.database.model.AccountModel; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; public class MessengerXmppConnection { private final XMPPConnection connection; - private final AccountModel account; + private final RoomAccountModel account; - public MessengerXmppConnection(XMPPConnection connection, AccountModel account) { + public MessengerXmppConnection(XMPPConnection connection, RoomAccountModel account) { this.connection = connection; this.account = account; } diff --git a/app/src/main/java/org/mercury_im/messenger/service/XmppService.java b/app/src/main/java/org/mercury_im/messenger/service/XmppService.java index 0c1e75c..844e928 100644 --- a/app/src/main/java/org/mercury_im/messenger/service/XmppService.java +++ b/app/src/main/java/org/mercury_im/messenger/service/XmppService.java @@ -3,17 +3,23 @@ package org.mercury_im.messenger.service; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; +import android.content.Context; import android.content.Intent; import android.os.IBinder; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; import android.util.Log; import android.util.LongSparseArray; import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.roster.Roster; +import org.jivesoftware.smack.roster.RosterEntry; +import org.jivesoftware.smack.roster.RosterLoadedListener; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jxmpp.jid.EntityBareJid; @@ -21,11 +27,15 @@ import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.Notifications; import org.mercury_im.messenger.R; -import org.mercury_im.messenger.persistence.database.AppDatabase; +import org.mercury_im.messenger.persistence.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.repository.RosterEntryRepository; +import org.mercury_im.messenger.persistence.room.AppDatabase; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; import org.mercury_im.messenger.ui.MainActivity; import java.io.IOException; import java.net.InetAddress; +import java.util.Set; import javax.inject.Inject; @@ -35,35 +45,38 @@ import javax.inject.Inject; */ public class XmppService extends Service { - private static final String TAG = MercuryImApplication.TAG; + private static final String TAG = MercuryImApplication.TAG; - private static final String APP = "org.olomono.mercury"; - private static final String SERVICE = APP + ".XmppService"; + private static final String APP = "org.olomono.mercury"; + private static final String SERVICE = APP + ".XmppService"; - private static final String ACTION = SERVICE + ".ACTION"; - private static final String EVENT = SERVICE + ".EVENT"; - private static final String EXTRA = SERVICE + ".EXTRA"; - private static final String STATUS = SERVICE + ".STATUS"; + private static final String ACTION = SERVICE + ".ACTION"; + private static final String EVENT = SERVICE + ".EVENT"; + private static final String EXTRA = SERVICE + ".EXTRA"; + private static final String STATUS = SERVICE + ".STATUS"; - public static final String ACTION_START = ACTION + ".START"; - public static final String ACTION_STOP = ACTION + ".STOP"; - public static final String ACTION_CONNECT = ACTION + ".CONNECT"; - public static final String ACTION_DISCONNECT = ACTION + ".DISCONNECT"; - public static final String ACTION_PING = ACTION + ".PING"; + public static final String ACTION_START = ACTION + ".START"; + public static final String ACTION_STOP = ACTION + ".STOP"; + public static final String ACTION_CONNECT = ACTION + ".CONNECT"; + public static final String ACTION_DISCONNECT = ACTION + ".DISCONNECT"; + public static final String ACTION_PING = ACTION + ".PING"; public static final String EVENT_INCOMING_MESSAGE = EVENT + ".INCOMING_MESSAGE"; public static final String EVENT_OUTGOING_MESSAGE = EVENT + ".OUTGOING_MESSAGE"; - public static final String EXTRA_JID = EXTRA + ".JID"; - public static final String EXTRA_PASSWORD = EXTRA + ".PASSWORD"; - public static final String EXTRA_ACCOUNT_ID = EXTRA + ".ACCOUNT_ID"; + public static final String EXTRA_JID = EXTRA + ".JID"; + public static final String EXTRA_PASSWORD = EXTRA + ".PASSWORD"; + public static final String EXTRA_ACCOUNT_ID = EXTRA + ".ACCOUNT_ID"; - public static final String STATUS_SUCCESS = STATUS + ".SUCCESS"; - public static final String STATUS_FAILURE = STATUS + ".FAILURE"; + public static final String STATUS_SUCCESS = STATUS + ".SUCCESS"; + public static final String STATUS_FAILURE = STATUS + ".FAILURE"; @Inject AppDatabase database; + @Inject + RosterEntryRepository rosterRepository; + private final LongSparseArray connections = new LongSparseArray<>(); @Nullable @@ -119,9 +132,7 @@ public class XmppService extends Service { public void run() { XMPPTCPConnection con = null; - try - - { + try { InetAddress address = InetAddress.getByName(bareJid.getDomain().toString()); XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder() .setXmppDomain(bareJid.asDomainBareJid()) @@ -131,32 +142,53 @@ public class XmppService extends Service { .build(); con = new XMPPTCPConnection(conf); con.connect().login(); - } catch( - XMPPException e) - - { + } catch ( + XMPPException e) { e.printStackTrace(); - } catch( - SmackException e) - - { + } catch ( + SmackException e) { e.printStackTrace(); - } catch( - IOException e) - - { + } catch ( + IOException e) { e.printStackTrace(); - } catch( - InterruptedException e) - - { + } catch ( + InterruptedException e) { e.printStackTrace(); } - connections.put(intent.getLongExtra(EXTRA_ACCOUNT_ID,-1),con); - while (true) { + connections.put(intent.getLongExtra(EXTRA_ACCOUNT_ID, -1), con); + NotificationManagerCompat.from(getApplicationContext()).notify(Notifications.FOREGROUND_SERVICE_ID, + getForegroundNotification(getApplicationContext(), connections.size())); + Roster roster = Roster.getInstanceFor(con); + roster.addRosterLoadedListener(new RosterLoadedListener() { + @Override + public void onRosterLoaded(Roster roster) { + Set entries = roster.getEntries(); + for (RosterEntry e : entries) { + Log.d(TAG, "Inserting Roster entry " + e.getJid().toString()); + RoomRosterEntryModel m = new RoomRosterEntryModel(e.getJid().asEntityBareJidIfPossible(), e.getName(), e.getName()); + m.setAccountId(accountId); + rosterRepository.updateOrInsertRosterEntry(m); + } + } + + @Override + public void onRosterLoadingFailed(Exception exception) { + Log.d(TAG, "Roster Loading failed", exception); + } + }); + + try { + roster.reload(); + } catch (SmackException.NotLoggedInException e) { + e.printStackTrace(); + } catch (SmackException.NotConnectedException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); } + } }.start(); break; @@ -170,22 +202,23 @@ public class XmppService extends Service { public void startAndDisplayForegroundNotification() { Log.d(TAG, "startAndDisplayForegroundNotification()"); - Intent startMainActivityIntent = new Intent(this, MainActivity.class); - PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, - startMainActivityIntent, 0); - - Notification notification = new NotificationCompat.Builder(this, - Notifications.NOTIFICATION_CHANNEL__FOREGROUND_SERVICE) - .setContentTitle("Sticky Notification Title") - .setContentText("Notification Content Text") - .setSmallIcon(R.drawable.ic_send_black_24dp) - .setContentIntent(pendingIntent) - .setTicker("Notification Ticker Text") - .build(); + Notification notification = getForegroundNotification(getApplicationContext(), connections.size()); startForeground(Notifications.FOREGROUND_SERVICE_ID, notification); } + static Notification getForegroundNotification(Context context, int numConnections) { + Intent startMainActivityIntent = new Intent(context, MainActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, + startMainActivityIntent, 0); + return new NotificationCompat.Builder(context, Notifications.NOTIFICATION_CHANNEL__FOREGROUND_SERVICE) + .setContentTitle("Mercury") + .setContentText(numConnections + " connections.") + .setSmallIcon(R.drawable.ic_send_black_24dp) + .setContentIntent(pendingIntent) + .build(); + } + public XMPPConnection getConnection(long accountId) { return connections.get(accountId); } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/MainActivity.java b/app/src/main/java/org/mercury_im/messenger/ui/MainActivity.java index 3a965e7..5ee21d8 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/MainActivity.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/MainActivity.java @@ -15,11 +15,11 @@ import android.view.View; import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.R; -import org.mercury_im.messenger.persistence.database.AppDatabase; -import org.mercury_im.messenger.persistence.database.model.AccountModel; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; -import org.mercury_im.messenger.persistence.repository.account.AccountRepository; -import org.mercury_im.messenger.persistence.repository.roster.RosterEntryRepository; +import org.mercury_im.messenger.persistence.room.AppDatabase; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; +import org.mercury_im.messenger.persistence.repository.AccountRepository; +import org.mercury_im.messenger.persistence.repository.RosterEntryRepository; import org.mercury_im.messenger.ui.chat.ChatActivity; import org.mercury_im.messenger.ui.login.LoginActivity; import org.mercury_im.messenger.ui.settings.SettingsActivity; @@ -50,7 +50,7 @@ public class MainActivity extends AppCompatActivity { fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - AccountModel account = new AccountModel(); + RoomAccountModel account = new RoomAccountModel(); account.setJid(JidCreate.entityBareFromOrThrowUnchecked("alice@wonderland.lit")); account.setPassword("swordfish"); @@ -58,9 +58,9 @@ public class MainActivity extends AppCompatActivity { } }); - accountRepository.getAllAccounts().observe(this, new Observer>() { + accountRepository.getAllAccounts().observe(this, new Observer>() { @Override - public void onChanged(@Nullable List accountModels) { + public void onChanged(@Nullable List accountModels) { if (accountModels == null || accountModels.isEmpty()) { startActivity(new Intent(getApplicationContext(), LoginActivity.class)); } @@ -96,11 +96,11 @@ public class MainActivity extends AppCompatActivity { return super.onOptionsItemSelected(item); } - private void addRosterEntry(AppDatabase database, RosterEntryModel rosterEntry) { + private void addRosterEntry(AppDatabase database, RoomRosterEntryModel rosterEntry) { new addRosterEntry(database).execute(rosterEntry); } - private static class addRosterEntry extends AsyncTask { + private static class addRosterEntry extends AsyncTask { private AppDatabase database; @@ -109,8 +109,8 @@ public class MainActivity extends AppCompatActivity { } @Override - protected Void doInBackground(RosterEntryModel... rosterEntryModels) { - database.rosterEntryDao().addRosterEntry(rosterEntryModels[0]); + protected Void doInBackground(RoomRosterEntryModel... rosterEntryModels) { + database.rosterEntryDao().insert(rosterEntryModels[0]); return null; } } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/chat/ChatViewModel.java b/app/src/main/java/org/mercury_im/messenger/ui/chat/ChatViewModel.java index 7791aa0..a3b677c 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/chat/ChatViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/chat/ChatViewModel.java @@ -3,14 +3,14 @@ package org.mercury_im.messenger.ui.chat; import androidx.lifecycle.ViewModel; import org.jxmpp.jid.EntityBareJid; -import org.mercury_im.messenger.persistence.database.model.Account; +import org.mercury_im.messenger.persistence.model.AccountModel; public class ChatViewModel extends ViewModel { - private Account account; + private AccountModel account; private EntityBareJid contact; - public void init(Account account, EntityBareJid contact) { + public void init(AccountModel account, EntityBareJid contact) { this.account = account; this.contact = contact; } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/login/LoginActivity.java b/app/src/main/java/org/mercury_im/messenger/ui/login/LoginActivity.java index 9435370..8901776 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/login/LoginActivity.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/login/LoginActivity.java @@ -17,8 +17,8 @@ import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.R; -import org.mercury_im.messenger.persistence.database.model.AccountModel; -import org.mercury_im.messenger.persistence.repository.account.AccountRepository; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; +import org.mercury_im.messenger.persistence.repository.AccountRepository; import org.mercury_im.messenger.service.XmppService; import javax.inject.Inject; @@ -101,7 +101,7 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito } if (loginIntact) { - AccountModel accountModel = new AccountModel(); + RoomAccountModel accountModel = new RoomAccountModel(); accountModel.setEnabled(true); accountModel.setJid(jid); accountModel.setPassword(password); diff --git a/app/src/main/java/org/mercury_im/messenger/ui/login/LoginViewModel.java b/app/src/main/java/org/mercury_im/messenger/ui/login/LoginViewModel.java index 9048ff6..ca4e599 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/login/LoginViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/login/LoginViewModel.java @@ -5,8 +5,8 @@ import androidx.lifecycle.ViewModel; import androidx.annotation.NonNull; import android.text.TextUtils; -import org.mercury_im.messenger.persistence.database.model.AccountModel; -import org.mercury_im.messenger.persistence.repository.account.AccountRepository; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; +import org.mercury_im.messenger.persistence.repository.AccountRepository; import javax.inject.Inject; @@ -16,23 +16,23 @@ public class LoginViewModel extends ViewModel { @Inject AccountRepository accountRepository; - private MutableLiveData account = new MutableLiveData<>(); + private MutableLiveData account = new MutableLiveData<>(); public LoginViewModel() { super(); - init(new AccountModel()); + init(new RoomAccountModel()); } - public void init(@NonNull AccountModel account) { + public void init(@NonNull RoomAccountModel account) { this.account.setValue(account); } - public MutableLiveData getAccount() { + public MutableLiveData getAccount() { return account; } public void login() { - AccountModel account = getAccount().getValue(); + RoomAccountModel account = getAccount().getValue(); if (account != null && account.getJid() != null && !TextUtils.isEmpty(account.getPassword())) { accountRepository.insertAccount(account); } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterFragment.java b/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterFragment.java index dcdc9a2..f948edb 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterFragment.java @@ -11,7 +11,7 @@ import android.view.View; import android.view.ViewGroup; import org.mercury_im.messenger.R; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; import java.util.ArrayList; import java.util.List; @@ -45,9 +45,9 @@ public class RosterFragment extends Fragment { } private void observeViewModel(RosterViewModel viewModel) { - viewModel.getRosterEntryList().observe(this, new Observer>() { + viewModel.getRosterEntryList().observe(this, new Observer>() { @Override - public void onChanged(@Nullable List rosterEntries) { + public void onChanged(@Nullable List rosterEntries) { if (rosterEntries == null) { return; } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterRecyclerViewAdapter.java b/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterRecyclerViewAdapter.java index e57ec46..8ee6e7d 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterRecyclerViewAdapter.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterRecyclerViewAdapter.java @@ -8,16 +8,16 @@ import android.view.ViewGroup; import android.widget.TextView; import org.mercury_im.messenger.R; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; import java.util.List; public class RosterRecyclerViewAdapter extends RecyclerView.Adapter { - private List entryModelList; + private List entryModelList; - public RosterRecyclerViewAdapter(List entryModelList) { + public RosterRecyclerViewAdapter(List entryModelList) { this.entryModelList = entryModelList; } @@ -30,7 +30,7 @@ public class RosterRecyclerViewAdapter @Override public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) { - RosterEntryModel model = entryModelList.get(position); + RoomRosterEntryModel model = entryModelList.get(position); holder.jidView.setText(model.getJid().toString()); holder.nicknameView.setText(model.getNickname()); holder.itemView.setTag(model); @@ -41,7 +41,7 @@ public class RosterRecyclerViewAdapter return entryModelList.size(); } - public void setItems(List rosterEntryModels) { + public void setItems(List rosterEntryModels) { this.entryModelList = rosterEntryModels; notifyDataSetChanged(); } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterViewModel.java b/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterViewModel.java index 6183321..8ab880c 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/roster/RosterViewModel.java @@ -6,8 +6,8 @@ import androidx.lifecycle.LiveData; import androidx.annotation.NonNull; import org.mercury_im.messenger.MercuryImApplication; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; -import org.mercury_im.messenger.persistence.repository.roster.RosterEntryRepository; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; +import org.mercury_im.messenger.persistence.repository.RosterEntryRepository; import java.util.List; @@ -18,7 +18,7 @@ public class RosterViewModel extends AndroidViewModel { @Inject RosterEntryRepository rosterEntryRepository; - private final LiveData> rosterEntryList; + private final LiveData> rosterEntryList; @Inject public RosterViewModel(@NonNull Application application) { @@ -27,7 +27,7 @@ public class RosterViewModel extends AndroidViewModel { this.rosterEntryList = rosterEntryRepository.getAllRosterEntries(); } - public LiveData> getRosterEntryList() { + public LiveData> getRosterEntryList() { return rosterEntryList; } } diff --git a/persistence-room/.gitignore b/persistence-room/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/persistence-room/.gitignore @@ -0,0 +1 @@ +/build diff --git a/persistence-room/build.gradle b/persistence-room/build.gradle new file mode 100644 index 0000000..abfe8e4 --- /dev/null +++ b/persistence-room/build.gradle @@ -0,0 +1,43 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + api project(":persistence") + + // Dagger 2 for dependency injection + implementation "com.google.dagger:dagger:$daggerVersion" + annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" + + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.0.2' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + + // Room + api "androidx.room:room-runtime:$roomVersion" + annotationProcessor "androidx.room:room-compiler:$roomVersion" +} diff --git a/persistence-room/proguard-rules.pro b/persistence-room/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/persistence-room/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/persistence-room/src/androidTest/java/org/mercury_im/messenger/persistence/room/ExampleInstrumentedTest.java b/persistence-room/src/androidTest/java/org/mercury_im/messenger/persistence/room/ExampleInstrumentedTest.java new file mode 100644 index 0000000..5277bb2 --- /dev/null +++ b/persistence-room/src/androidTest/java/org/mercury_im/messenger/persistence/room/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package org.mercury_im.messenger.persistence.room; + +import android.content.Context; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("org.mercury_im.messenger.persistence.room", appContext.getPackageName()); + } +} diff --git a/persistence-room/src/main/AndroidManifest.xml b/persistence-room/src/main/AndroidManifest.xml new file mode 100644 index 0000000..31593cb --- /dev/null +++ b/persistence-room/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/AppDatabase.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/AppDatabase.java similarity index 52% rename from app/src/main/java/org/mercury_im/messenger/persistence/database/AppDatabase.java rename to persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/AppDatabase.java index 34832b6..fb997fa 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/AppDatabase.java +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/AppDatabase.java @@ -1,4 +1,4 @@ -package org.mercury_im.messenger.persistence.database; +package org.mercury_im.messenger.persistence.room; import android.content.Context; @@ -6,12 +6,14 @@ import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; -import org.mercury_im.messenger.persistence.database.dao.AccountDao; -import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao; -import org.mercury_im.messenger.persistence.database.model.AccountModel; -import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.room.dao.AccountDao; +import org.mercury_im.messenger.persistence.room.dao.MessageDao; +import org.mercury_im.messenger.persistence.room.dao.RosterEntryDao; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; +import org.mercury_im.messenger.persistence.room.model.RoomMessageModel; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; -@Database(entities = {RosterEntryModel.class, AccountModel.class}, version = 1) +@Database(entities = {RoomRosterEntryModel.class, RoomAccountModel.class, RoomMessageModel.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public static final String DB_NAME = "app_db"; @@ -27,5 +29,7 @@ public abstract class AppDatabase extends RoomDatabase { public abstract RosterEntryDao rosterEntryDao(); + public abstract MessageDao messageDao(); + public abstract AccountDao accountDao(); } diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/AccountDao.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/AccountDao.java new file mode 100644 index 0000000..3d5c6ce --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/AccountDao.java @@ -0,0 +1,44 @@ +package org.mercury_im.messenger.persistence.room.dao; + +import androidx.lifecycle.LiveData; +import androidx.annotation.WorkerThread; +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.TypeConverters; +import androidx.room.Update; + +import org.jxmpp.jid.EntityBareJid; +import org.mercury_im.messenger.persistence.model.AccountModel; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; +import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter; + +import java.util.List; + +@Dao +@TypeConverters(EntityBareJidConverter.class) +@WorkerThread +public interface AccountDao extends BaseDao { + + /** + * Return a {@link LiveData} wrapping a {@link List} which contains all + * {@link RoomAccountModel Accounts} which are currently stored in the database. + * + * @return live updating account list + */ + @Query("select * from accounts") + LiveData> getAllAccounts(); + + /** + * Return the {@link RoomAccountModel Account} which is identified by the given id. + * + * @param id id of the account + * @return account or null + */ + @Query("select * from accounts where id = :id") + LiveData getAccountById(long id); + + @Query("select * from accounts where jid = :jid") + LiveData getAccountByJid(EntityBareJid jid); +} diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/BaseDao.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/BaseDao.java new file mode 100644 index 0000000..72e3fdf --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/BaseDao.java @@ -0,0 +1,17 @@ +package org.mercury_im.messenger.persistence.room.dao; + +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Update; + +public interface BaseDao { + + @Insert + long insert(T entity); + + @Update + void update(T entity); + + @Delete + void delete(T entity); +} diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/MessageDao.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/MessageDao.java new file mode 100644 index 0000000..33ba034 --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/MessageDao.java @@ -0,0 +1,24 @@ +package org.mercury_im.messenger.persistence.room.dao; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Query; +import androidx.room.TypeConverters; + +import org.jxmpp.jid.EntityFullJid; +import org.mercury_im.messenger.persistence.room.model.RoomMessageModel; +import org.mercury_im.messenger.persistence.room.type_converter.EntityFullJidConverter; + +import java.util.List; + +@Dao +@TypeConverters(EntityFullJidConverter.class) +public interface MessageDao extends BaseDao { + + @Query("SELECT * FROM messages WHERE accountId=:accountId ORDER BY sendDate DESC") + LiveData> getAllMessagesOf(long accountId); + + @Query("SELECT * FROM messages WHERE accountId=:accountId AND `from`=:sender ORDER BY sendDate DESC") + LiveData> getAllMessagesFrom(long accountId, EntityFullJid sender); + +} diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/RosterEntryDao.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/RosterEntryDao.java new file mode 100644 index 0000000..d6f88d9 --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/dao/RosterEntryDao.java @@ -0,0 +1,35 @@ +package org.mercury_im.messenger.persistence.room.dao; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.TypeConverters; + +import org.mercury_im.messenger.persistence.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; + +import java.util.List; + +import static androidx.room.OnConflictStrategy.REPLACE; + +@Dao +@TypeConverters(EntityBareJidConverter.class) +public interface RosterEntryDao extends BaseDao { + + /** + * Return a {@link LiveData} wrapping a {@link List} of all {@link RoomRosterEntryModel RosterEntries} + * which are currently found in the database. + * @return + */ + @Query("select * from roster") + LiveData> getAllRosterEntries(); + + @Query("select * from roster where id = :id") + RoomRosterEntryModel getRosterEntryById(long id); + + @Query("select * from roster where accountId = :accountId") + LiveData> getRosterEntriesForAccount(long accountId); +} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/model/AccountModel.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomAccountModel.java similarity index 70% rename from app/src/main/java/org/mercury_im/messenger/persistence/database/model/AccountModel.java rename to persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomAccountModel.java index 6d97a05..15ccf04 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/model/AccountModel.java +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomAccountModel.java @@ -1,4 +1,4 @@ -package org.mercury_im.messenger.persistence.database.model; +package org.mercury_im.messenger.persistence.room.model; import androidx.room.ColumnInfo; @@ -7,10 +7,11 @@ import androidx.room.PrimaryKey; import androidx.room.TypeConverters; import org.jxmpp.jid.EntityBareJid; -import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; +import org.mercury_im.messenger.persistence.model.AccountModel; +import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter; -@Entity -public class AccountModel implements Account { +@Entity(tableName = "accounts") +public class RoomAccountModel implements AccountModel { @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") @@ -26,6 +27,16 @@ public class AccountModel implements Account { @ColumnInfo(name = "enabled") private boolean enabled; + @Override + public long getId() { + return id; + } + + @Override + public void setId(long id) { + this.id = id; + } + @Override public EntityBareJid getJid() { return jid; diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomMessageModel.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomMessageModel.java new file mode 100644 index 0000000..2c73d15 --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomMessageModel.java @@ -0,0 +1,101 @@ +package org.mercury_im.messenger.persistence.room.model; + +import androidx.room.Entity; +import androidx.room.ForeignKey; +import androidx.room.PrimaryKey; +import androidx.room.TypeConverter; +import androidx.room.TypeConverters; + +import org.jxmpp.jid.EntityFullJid; +import org.mercury_im.messenger.persistence.model.MessageModel; +import org.mercury_im.messenger.persistence.room.type_converter.DateConverter; +import org.mercury_im.messenger.persistence.room.type_converter.EntityFullJidConverter; + +import java.util.Date; + +import static androidx.room.ForeignKey.CASCADE; + +@Entity(tableName = "messages", foreignKeys = @ForeignKey(entity = RoomAccountModel.class, + parentColumns = "id", childColumns = "accountId", onDelete = CASCADE)) +public class RoomMessageModel implements MessageModel { + + @PrimaryKey(autoGenerate = true) + private long id; + + private long accountId; + + private String body; + + @TypeConverters(DateConverter.class) + private Date sendDate; + + @TypeConverters(EntityFullJidConverter.class) + private EntityFullJid from; + + @TypeConverters(EntityFullJidConverter.class) + private EntityFullJid to; + + public RoomMessageModel() { + + } + + @Override + public long getId() { + return id; + } + + @Override + public void setId(long val) { + this.id = val; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + @Override + public String getBody() { + return body; + } + + @Override + public void setBody(String body) { + this.body = body; + } + + @Override + public Date getSendDate() { + return sendDate; + } + + @Override + public void setSendDate(Date date) { + this.sendDate = date; + } + + @Override + public EntityFullJid getFrom() { + return from; + } + + @Override + public void setFrom(EntityFullJid sender) { + this.from = sender; + } + + @Override + public EntityFullJid getTo() { + return to; + } + + @Override + public void setTo(EntityFullJid recipient) { + this.to = recipient; + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/model/RosterEntryModel.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomRosterEntryModel.java similarity index 58% rename from app/src/main/java/org/mercury_im/messenger/persistence/database/model/RosterEntryModel.java rename to persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomRosterEntryModel.java index 97a3395..f4d4713 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/model/RosterEntryModel.java +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/model/RoomRosterEntryModel.java @@ -1,4 +1,4 @@ -package org.mercury_im.messenger.persistence.database.model; +package org.mercury_im.messenger.persistence.room.model; import androidx.room.Entity; @@ -7,20 +7,21 @@ import androidx.room.PrimaryKey; import androidx.room.TypeConverters; import org.jxmpp.jid.EntityBareJid; -import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; +import org.mercury_im.messenger.persistence.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter; import static androidx.room.ForeignKey.CASCADE; -@Entity(foreignKeys = @ForeignKey(entity = AccountModel.class, +@Entity(tableName = "roster", foreignKeys = @ForeignKey(entity = RoomAccountModel.class, parentColumns = "id", childColumns = "accountId", onDelete = CASCADE)) -public class RosterEntryModel { +public class RoomRosterEntryModel implements RosterEntryModel { @PrimaryKey(autoGenerate = true) - public int id; + public long id; - private int accountId; + private long accountId; @TypeConverters(EntityBareJidConverter.class) private EntityBareJid jid; @@ -29,38 +30,54 @@ public class RosterEntryModel { private String nickname; - - public RosterEntryModel(EntityBareJid jid, String rosterName, String nickname) { + public RoomRosterEntryModel(EntityBareJid jid, String rosterName, String nickname) { this.jid = jid; this.nickname = nickname; this.rosterName = rosterName; } + @Override + public long getId() { + return id; + } + + @Override + public void setId(long id) { + this.id = id; + } + + @Override public EntityBareJid getJid() { return jid; } + @Override public String getRosterName() { return rosterName; } + @Override public void setRosterName(String rosterName) { this.rosterName = rosterName; } + @Override public String getNickname() { return nickname; } + @Override public void setNickname(String nickname) { this.nickname = nickname; } - public int getAccountId() { + @Override + public long getAccountId() { return accountId; } - public void setAccountId(int accountId) { + @Override + public void setAccountId(long accountId) { this.accountId = accountId; } } diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepositoryImpl.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IAccountRepository.java similarity index 56% rename from app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepositoryImpl.java rename to persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IAccountRepository.java index 6f26af8..a752ddb 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/repository/account/AccountRepositoryImpl.java +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IAccountRepository.java @@ -1,37 +1,39 @@ -package org.mercury_im.messenger.persistence.repository.account; +package org.mercury_im.messenger.persistence.room.repository; -import androidx.lifecycle.LiveData; import android.os.AsyncTask; -import org.mercury_im.messenger.persistence.database.dao.AccountDao; -import org.mercury_im.messenger.persistence.database.model.AccountModel; +import androidx.lifecycle.LiveData; + +import org.mercury_im.messenger.persistence.repository.AccountRepository; +import org.mercury_im.messenger.persistence.room.dao.AccountDao; +import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; import java.util.List; import java.util.concurrent.ExecutionException; import javax.inject.Inject; -public class AccountRepositoryImpl implements AccountRepository { +public class IAccountRepository implements AccountRepository { private final AccountDao accountDao; @Inject - public AccountRepositoryImpl(AccountDao accountDao) { + public IAccountRepository(AccountDao accountDao) { this.accountDao = accountDao; } @Override - public LiveData getAccount(long accountId) { + public LiveData getAccount(long accountId) { return accountDao.getAccountById(accountId); } @Override - public LiveData> getAllAccounts() { + public LiveData> getAllAccounts() { return accountDao.getAllAccounts(); } @Override - public long insertAccount(AccountModel accountModel) { + public long insertAccount(RoomAccountModel accountModel) { InsertAsyncTask task = new InsertAsyncTask(accountDao); try { return task.execute(accountModel).get(); @@ -43,7 +45,7 @@ public class AccountRepositoryImpl implements AccountRepository { return -1; } - private static class InsertAsyncTask extends AsyncTask { + private static class InsertAsyncTask extends AsyncTask { private final AccountDao accountDao; @@ -52,15 +54,15 @@ public class AccountRepositoryImpl implements AccountRepository { } @Override - protected Long doInBackground(AccountModel... accountModels) { - for (AccountModel accountModel : accountModels) { - return accountDao.insertAccount(accountModel); + protected Long doInBackground(RoomAccountModel... accountModels) { + for (RoomAccountModel accountModel : accountModels) { + return accountDao.insert(accountModel); } return null; } } - private static class QueryAsyncTask extends AsyncTask> { + private static class QueryAsyncTask extends AsyncTask> { private final AccountDao accountDao; @@ -69,7 +71,7 @@ public class AccountRepositoryImpl implements AccountRepository { } @Override - protected LiveData doInBackground(Long... longs) { + protected LiveData doInBackground(Long... longs) { return accountDao.getAccountById(longs[0]); } } diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IMessageRepository.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IMessageRepository.java new file mode 100644 index 0000000..1ae2906 --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IMessageRepository.java @@ -0,0 +1,7 @@ +package org.mercury_im.messenger.persistence.room.repository; + +import org.mercury_im.messenger.persistence.repository.MessageRepository; +import org.mercury_im.messenger.persistence.room.model.RoomMessageModel; + +public class IMessageRepository implements MessageRepository { +} diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IRosterEntryRepository.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IRosterEntryRepository.java new file mode 100644 index 0000000..aedc2c2 --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/repository/IRosterEntryRepository.java @@ -0,0 +1,31 @@ +package org.mercury_im.messenger.persistence.room.repository; + +import androidx.lifecycle.LiveData; + +import org.mercury_im.messenger.persistence.model.RosterEntryModel; +import org.mercury_im.messenger.persistence.repository.RosterEntryRepository; +import org.mercury_im.messenger.persistence.room.dao.RosterEntryDao; +import org.mercury_im.messenger.persistence.room.model.RoomRosterEntryModel; + +import java.util.List; + +public class IRosterEntryRepository implements RosterEntryRepository { + + private final RosterEntryDao rosterEntryDao; + + public IRosterEntryRepository(RosterEntryDao dao) { + this.rosterEntryDao = dao; + } + + @Override + public LiveData> getAllRosterEntries() { + return rosterEntryDao.getAllRosterEntries(); + } + + @Override + public void updateOrInsertRosterEntry(RoomRosterEntryModel rosterEntryModel) { + rosterEntryDao.insert(rosterEntryModel); + } + + +} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/type_converter/BareJidConverter.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/BareJidConverter.java similarity index 89% rename from app/src/main/java/org/mercury_im/messenger/persistence/database/type_converter/BareJidConverter.java rename to persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/BareJidConverter.java index a07b168..cafaa4e 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/type_converter/BareJidConverter.java +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/BareJidConverter.java @@ -1,4 +1,4 @@ -package org.mercury_im.messenger.persistence.database.type_converter; +package org.mercury_im.messenger.persistence.room.type_converter; import androidx.room.TypeConverter; diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/DateConverter.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/DateConverter.java new file mode 100644 index 0000000..fa520e4 --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/DateConverter.java @@ -0,0 +1,18 @@ +package org.mercury_im.messenger.persistence.room.type_converter; + +import androidx.room.TypeConverter; + +import java.util.Date; + +public class DateConverter { + + @TypeConverter + public static long toLong(Date date) { + return date.getTime(); + } + + @TypeConverter + public static Date toDate(long lon) { + return new Date(lon); + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/type_converter/EntityBareJidConverter.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityBareJidConverter.java similarity index 90% rename from app/src/main/java/org/mercury_im/messenger/persistence/database/type_converter/EntityBareJidConverter.java rename to persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityBareJidConverter.java index 61b64d1..011e41f 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/type_converter/EntityBareJidConverter.java +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityBareJidConverter.java @@ -1,4 +1,4 @@ -package org.mercury_im.messenger.persistence.database.type_converter; +package org.mercury_im.messenger.persistence.room.type_converter; import androidx.room.TypeConverter; diff --git a/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityFullJidConverter.java b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityFullJidConverter.java new file mode 100644 index 0000000..b1e3c1a --- /dev/null +++ b/persistence-room/src/main/java/org/mercury_im/messenger/persistence/room/type_converter/EntityFullJidConverter.java @@ -0,0 +1,25 @@ +package org.mercury_im.messenger.persistence.room.type_converter; + +import androidx.room.TypeConverter; + +import org.jxmpp.jid.EntityFullJid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.stringprep.XmppStringprepException; + +public class EntityFullJidConverter { + + @TypeConverter + public static String toString(EntityFullJid jid) { + return jid != null ? jid.toString() : null; + } + + @TypeConverter + public static EntityFullJid toEntityFullJid(String string) { + try { + return string != null ? JidCreate.entityFullFrom(string) : null; + } catch (XmppStringprepException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/persistence-room/src/main/res/values/strings.xml b/persistence-room/src/main/res/values/strings.xml new file mode 100644 index 0000000..efae4dd --- /dev/null +++ b/persistence-room/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + RoomDatabase + diff --git a/persistence-room/src/test/java/org/mercury_im/messenger/persistence/room/ExampleUnitTest.java b/persistence-room/src/test/java/org/mercury_im/messenger/persistence/room/ExampleUnitTest.java new file mode 100644 index 0000000..f736385 --- /dev/null +++ b/persistence-room/src/test/java/org/mercury_im/messenger/persistence/room/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package org.mercury_im.messenger.persistence.room; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/persistence/.gitignore b/persistence/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/persistence/.gitignore @@ -0,0 +1 @@ +/build diff --git a/persistence/build.gradle b/persistence/build.gradle new file mode 100644 index 0000000..88db8a2 --- /dev/null +++ b/persistence/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + + api('org.jxmpp:jxmpp-jid') { + version { + prefer 'latest.release' + } + } + + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.0.2' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/persistence/proguard-rules.pro b/persistence/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/persistence/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/persistence/src/androidTest/java/org/mercury_im/messenger/persistence/ExampleInstrumentedTest.java b/persistence/src/androidTest/java/org/mercury_im/messenger/persistence/ExampleInstrumentedTest.java new file mode 100644 index 0000000..1f7c501 --- /dev/null +++ b/persistence/src/androidTest/java/org/mercury_im/messenger/persistence/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package org.mercury_im.messenger.persistence; + +import android.content.Context; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("org.mercury_im.messenger.persistence.test", appContext.getPackageName()); + } +} diff --git a/persistence/src/main/AndroidManifest.xml b/persistence/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b2e794b --- /dev/null +++ b/persistence/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/app/src/main/java/org/mercury_im/messenger/persistence/database/model/Account.java b/persistence/src/main/java/org/mercury_im/messenger/persistence/model/AccountModel.java similarity index 64% rename from app/src/main/java/org/mercury_im/messenger/persistence/database/model/Account.java rename to persistence/src/main/java/org/mercury_im/messenger/persistence/model/AccountModel.java index d818c6d..25ea7c6 100644 --- a/app/src/main/java/org/mercury_im/messenger/persistence/database/model/Account.java +++ b/persistence/src/main/java/org/mercury_im/messenger/persistence/model/AccountModel.java @@ -1,8 +1,12 @@ -package org.mercury_im.messenger.persistence.database.model; +package org.mercury_im.messenger.persistence.model; import org.jxmpp.jid.EntityBareJid; -public interface Account { +public interface AccountModel { + + long getId(); + + void setId(long id); String getPassword(); diff --git a/persistence/src/main/java/org/mercury_im/messenger/persistence/model/MessageModel.java b/persistence/src/main/java/org/mercury_im/messenger/persistence/model/MessageModel.java new file mode 100644 index 0000000..f1914b7 --- /dev/null +++ b/persistence/src/main/java/org/mercury_im/messenger/persistence/model/MessageModel.java @@ -0,0 +1,32 @@ +package org.mercury_im.messenger.persistence.model; + +import org.jxmpp.jid.EntityFullJid; + +import java.util.Date; + +public interface MessageModel { + + long getId(); + + void setId(long val); + + long getAccountId(); + + void setAccountId(long accountId); + + String getBody(); + + void setBody(String body); + + Date getSendDate(); + + void setSendDate(Date date); + + EntityFullJid getFrom(); + + void setFrom(EntityFullJid sender); + + EntityFullJid getTo(); + + void setTo(EntityFullJid recipient); +} diff --git a/persistence/src/main/java/org/mercury_im/messenger/persistence/model/RosterEntryModel.java b/persistence/src/main/java/org/mercury_im/messenger/persistence/model/RosterEntryModel.java new file mode 100644 index 0000000..a539305 --- /dev/null +++ b/persistence/src/main/java/org/mercury_im/messenger/persistence/model/RosterEntryModel.java @@ -0,0 +1,24 @@ +package org.mercury_im.messenger.persistence.model; + +import org.jxmpp.jid.EntityBareJid; + +public interface RosterEntryModel { + + long getId(); + + void setId(long id); + + EntityBareJid getJid(); + + String getRosterName(); + + void setRosterName(String rosterName); + + String getNickname(); + + void setNickname(String nickname); + + long getAccountId(); + + void setAccountId(long accountId); +} diff --git a/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/AccountRepository.java b/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/AccountRepository.java new file mode 100644 index 0000000..8edf448 --- /dev/null +++ b/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/AccountRepository.java @@ -0,0 +1,16 @@ +package org.mercury_im.messenger.persistence.repository; + +import androidx.lifecycle.LiveData; + +import org.mercury_im.messenger.persistence.model.AccountModel; + +import java.util.List; + +public interface AccountRepository { + + LiveData getAccount(long accountId); + + LiveData> getAllAccounts(); + + long insertAccount(E accountModel); +} diff --git a/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/MessageRepository.java b/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/MessageRepository.java new file mode 100644 index 0000000..6c1dbbf --- /dev/null +++ b/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/MessageRepository.java @@ -0,0 +1,7 @@ +package org.mercury_im.messenger.persistence.repository; + +import org.mercury_im.messenger.persistence.model.MessageModel; + +public interface MessageRepository { + +} diff --git a/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/RosterEntryRepository.java b/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/RosterEntryRepository.java new file mode 100644 index 0000000..c91f510 --- /dev/null +++ b/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/RosterEntryRepository.java @@ -0,0 +1,14 @@ +package org.mercury_im.messenger.persistence.repository; + +import androidx.lifecycle.LiveData; + +import org.mercury_im.messenger.persistence.model.RosterEntryModel; + +import java.util.List; + +public interface RosterEntryRepository { + + LiveData> getAllRosterEntries(); + + void updateOrInsertRosterEntry(E rosterEntryModel); +} diff --git a/persistence/src/main/res/values/strings.xml b/persistence/src/main/res/values/strings.xml new file mode 100644 index 0000000..329a6b3 --- /dev/null +++ b/persistence/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Persistence + diff --git a/persistence/src/test/java/org/mercury_im/messenger/persistence/ExampleUnitTest.java b/persistence/src/test/java/org/mercury_im/messenger/persistence/ExampleUnitTest.java new file mode 100644 index 0000000..dc37a4b --- /dev/null +++ b/persistence/src/test/java/org/mercury_im/messenger/persistence/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package org.mercury_im.messenger.persistence; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e7b4def..c9fd981 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app' +include ':app', ':xmpp_core', ':persistence-room', ':persistence' diff --git a/xmpp_core/.gitignore b/xmpp_core/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/xmpp_core/.gitignore @@ -0,0 +1 @@ +/build diff --git a/xmpp_core/build.gradle b/xmpp_core/build.gradle new file mode 100644 index 0000000..f423b31 --- /dev/null +++ b/xmpp_core/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'java-library' + +dependencies { + // Smack + // Not all of those are needed, but it may be a good idea to define those versions explicitly + api "org.igniterealtime.smack:smack-android:$smackAndroidVersion" + api "org.igniterealtime.smack:smack-android-extensions:$smackAndroidExtensionsVersion" + api "org.igniterealtime.smack:smack-core:$smackCoreVersion" + api "org.igniterealtime.smack:smack-experimental:$smackExperimentalVersion" + api "org.igniterealtime.smack:smack-extensions:$smackExtensionsVersion" + api "org.igniterealtime.smack:smack-im:$smackImVersion" + api "org.igniterealtime.smack:smack-omemo:$smackOmemoVersion" + api "org.igniterealtime.smack:smack-omemo-signal:$smackOmemoSignalVersion" + api "org.igniterealtime.smack:smack-openpgp:$smackOpenPGPVersion" + api "org.igniterealtime.smack:smack-resolver-minidns:$smackResolverMiniDnsVersion" + api "org.igniterealtime.smack:smack-tcp:$smackTcpVersion" + + // Exclude XmlPullParser from Smack dependencies, as its now provided by Android + // https://stackoverflow.com/questions/48488563/gradle-xpp3-error/48746294#48746294 + configurations { + all*.exclude group: 'xpp3', module: 'xpp3' + } +} + +sourceCompatibility = "8" +targetCompatibility = "8" diff --git a/xmpp_core/src/main/java/org/mercury_im/xmpp_core/MercuryConnection.java b/xmpp_core/src/main/java/org/mercury_im/xmpp_core/MercuryConnection.java new file mode 100644 index 0000000..23b2ec5 --- /dev/null +++ b/xmpp_core/src/main/java/org/mercury_im/xmpp_core/MercuryConnection.java @@ -0,0 +1,16 @@ +package org.mercury_im.xmpp_core; + +import org.jivesoftware.smack.XMPPConnection; + +public class MercuryConnection { + + private final XMPPConnection connection; + + public MercuryConnection(XMPPConnection connection) { + this.connection = connection; + } + + public XMPPConnection getConnection() { + return connection; + } +}