order);
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/intentservice/FireBaseIntentService.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/intentservice/FireBaseIntentService.java
new file mode 100644
index 0000000..269e23d
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/intentservice/FireBaseIntentService.java
@@ -0,0 +1,144 @@
+package com.fazemeright.chatbotmetcs622.intentservice;
+
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Intent;
+import android.os.Build;
+import android.os.PowerManager;
+
+import androidx.annotation.Nullable;
+import androidx.core.app.NotificationCompat;
+
+import com.fazemeright.chatbotmetcs622.ChatBotApp;
+import com.fazemeright.chatbotmetcs622.R;
+import com.fazemeright.chatbotmetcs622.database.ChatBotDatabase;
+import com.fazemeright.chatbotmetcs622.database.messages.Message;
+import com.fazemeright.chatbotmetcs622.repositories.MessageRepository;
+import com.fazemeright.firebase_api_library.api.FireBaseApiManager;
+import com.fazemeright.firebase_api_library.listeners.DBValueListener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import timber.log.Timber;
+
+public class FireBaseIntentService extends IntentService {
+
+ public static final String ACTION_ADD_MESSAGE = "AddMessage";
+ public static final String ACTION_SYNC_MESSAGES = "SyncMessages";
+ /**
+ * TAG for logs
+ */
+ private static final String TAG = "FireBaseIntentService";
+ /**
+ * Use to send data with intent
+ */
+ public static final String ACTION = "IntentAction";
+ public static final String MESSAGE = "Message";
+ public static final String RESULT_RECEIVER = "ResultReceiver";
+
+ protected ChatBotDatabase database;
+ private PowerManager.WakeLock wakeLock;
+ private FireBaseApiManager fireBaseApiManager;
+ private MessageRepository messageRepository;
+
+ /**
+ * Creates an IntentService. Invoked by your subclass's constructor.
+ *
+ * TAG Used to name the worker thread, important only for debugging.
+ */
+ public FireBaseIntentService() {
+ super(TAG);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Timber.i("onCreate");
+ database = ChatBotDatabase.getInstance(getApplicationContext());
+ PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
+ if (powerManager != null) {
+ wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ChatBot:WakeLockTag");
+ wakeLock.acquire(60 * 1000); // acquire CPU
+ Timber.i("onCreate: Wake Lock acquired");
+ }
+ showForegroundServiceNotification("Chat Bot", "Syncing Messages...");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ Timber.i("onDestroy");
+ wakeLock.release();
+ Timber.i("onDestroy: Wake Lock released");
+
+ }
+
+ @Override
+ protected void onHandleIntent(@Nullable Intent intent) {
+ Timber.d("onHandleIntent");
+ if (intent != null) {
+ switch (intent.getStringExtra(ACTION)) {
+ case ACTION_ADD_MESSAGE:
+ addMessageToFireStore((Message) intent.getSerializableExtra(MESSAGE));
+ break;
+ case ACTION_SYNC_MESSAGES:
+ syncMessages();
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * Call to sync messages from FireStore to Room for the logged in user
+ */
+ private void syncMessages() {
+ /*try {
+ Thread.sleep(5000); // intentionally kept delay to show in presentation TODO: Remove afterwards
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }*/
+ messageRepository.syncMessagesFromFireStoreToRoom();
+ }
+
+ /**
+ * Call to add given message to FireStore
+ *
+ * @param message given message
+ */
+ private void addMessageToFireStore(Message message) {
+ messageRepository.addMessageToFireBase(Message.getHashMap(message));
+ }
+
+ /**
+ * Call to display foreground running notification to notify user of a background operation running
+ *
+ * @param title title to display in notification
+ * @param text text to display in notification
+ */
+ private void showForegroundServiceNotification(String title, String text) {
+ Timber.i("Show notification called");
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+
+ Notification notification = new NotificationCompat.Builder(this, ChatBotApp.CHANNEL_ID)
+ .setContentTitle(title)
+ .setContentText(text)
+ .setSmallIcon(R.drawable.ic_launcher_foreground)
+ .setPriority(NotificationManager.IMPORTANCE_DEFAULT)
+ .build();
+
+ startForeground(1, notification);
+ }
+ }
+
+ @Override
+ public void onStart(@Nullable Intent intent, int startId) {
+ super.onStart(intent, startId);
+ fireBaseApiManager = FireBaseApiManager.getInstance();
+ messageRepository = MessageRepository.getInstance(getApplicationContext());
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/models/ChatRoom.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/models/ChatRoom.java
new file mode 100644
index 0000000..45e002d
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/models/ChatRoom.java
@@ -0,0 +1,48 @@
+package com.fazemeright.chatbotmetcs622.models;
+
+import java.io.Serializable;
+
+/**
+ * POJO to hold Chat room
+ */
+public class ChatRoom implements Serializable {
+ public static final int BRUTE_FORCE_ID = 0;
+ public static final int LUCENE_ID = 1;
+ public static final int MONGO_DB_ID = 2;
+ public static final int MY_SQL_ID = 3;
+
+ public static final String MONGO_DB = "MongoDB";
+ public static final String MY_SQL = "MySQL";
+ public static final String LUCENE = "Lucene";
+ public static final String BRUTE_FORCE = "Brute Force";
+ /**
+ * is of the chat room
+ */
+ private long id;
+ /**
+ * Name of the chat room
+ */
+ private String name;
+ /**
+ * Id of resource file associated with the ChatRoom
+ */
+ private int logoId;
+
+ public ChatRoom(int id, String name, int logoId) {
+ this.id = id;
+ this.name = name;
+ this.logoId = logoId;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getLogoId() {
+ return logoId;
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/ApiManager.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/ApiManager.java
new file mode 100644
index 0000000..e18117e
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/ApiManager.java
@@ -0,0 +1,112 @@
+package com.fazemeright.chatbotmetcs622.network;
+
+import android.content.Context;
+
+import com.fazemeright.chatbotmetcs622.database.messages.Message;
+import com.fazemeright.chatbotmetcs622.models.ChatRoom;
+import com.fazemeright.chatbotmetcs622.network.handlers.NetworkCallback;
+import com.fazemeright.chatbotmetcs622.network.handlers.NetworkWrapper;
+import com.fazemeright.chatbotmetcs622.network.models.NetError;
+import com.fazemeright.chatbotmetcs622.network.models.NetResponse;
+import com.fazemeright.chatbotmetcs622.network.models.request.MessageQueryRequestModel;
+import com.fazemeright.chatbotmetcs622.network.models.response.QueryResponseMessage;
+import com.google.gson.reflect.TypeToken;
+
+public class ApiManager {
+
+ private static ApiManager apiManager = null;
+ private NetworkManager networkManager;
+
+ public static ApiManager getInstance() {
+ if (apiManager == null) {
+ apiManager = new ApiManager();
+ }
+ return apiManager;
+ }
+
+ /**
+ * Initialize base url,alias key and {@link NetworkWrapper} from application side,
+ * so that no need to pass base url in every user related network call.
+ *
+ * @param networkManager
+ */
+ public void init(NetworkManager networkManager) {
+ this.networkManager = networkManager;
+
+ }
+
+
+ /**
+ * Call Query API to backend to fetch results for the given Message query
+ *
+ * @param context context
+ * @param newMessage given message query
+ * @param networkCallback callback to listen to response
+ */
+ public void queryDatabase(Context context, Message newMessage,
+ final NetworkCallback networkCallback) {
+ String serverEndPoint;
+ switch ((int) newMessage.getChatRoomId()) {
+ case ChatRoom.BRUTE_FORCE_ID:
+ serverEndPoint = DatabaseUrl.BRUTE_FORCE;
+ break;
+ case ChatRoom.LUCENE_ID:
+ serverEndPoint = DatabaseUrl.LUCENE;
+ break;
+ case ChatRoom.MONGO_DB_ID:
+ serverEndPoint = DatabaseUrl.MONGO_DB;
+ break;
+ default:
+ serverEndPoint = DatabaseUrl.MY_SQL;
+ break;
+ }
+ String url = BaseUrl.BASE_URL.concat(BaseUrl.BASE_APP_NAME).concat(serverEndPoint);
+
+ MessageQueryRequestModel messageQuery = new MessageQueryRequestModel(newMessage.getMsg());
+
+ TypeToken typeToken = new TypeToken() {
+ };
+ networkManager.makePostRequest(context, url, messageQuery, typeToken, "", new NetworkCallback() {
+ @Override
+ public void onSuccess(NetResponse response) {
+ networkCallback.onSuccess(response);
+ }
+
+ @Override
+ public void onError(NetError error) {
+ networkCallback.onError(error);
+ }
+ });
+
+ }
+
+ /**
+ * DatabaseUrl module Api sub url
+ */
+ static class DatabaseUrl {
+ final static String MONGO_DB = "/mongodb";
+ final static String LUCENE = "/lucene";
+ final static String MY_SQL = "/mysql";
+ final static String BRUTE_FORCE = "/bruteforce";
+
+ }
+
+ /**
+ * baseURL model for all the BASE URL addresses
+ */
+ public static class BaseUrl {
+ static String BASE_URL = "http://192.168.43.28:8080"; // Update the url as per your local ip address
+ final static String BASE_APP_NAME = "/MET_CS622_ChatBot_Backend_war_exploded";
+
+ /**
+ * Set the local IP address or the base url address for the server where the database back end is hosted.
+ * Also include the port.
+ *
+ * @param hostAddress ip address
+ */
+ public static void setLocalIP(String hostAddress) {
+ BASE_URL = hostAddress;
+ }
+
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/NetworkManager.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/NetworkManager.java
new file mode 100644
index 0000000..6921e00
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/NetworkManager.java
@@ -0,0 +1,498 @@
+package com.fazemeright.chatbotmetcs622.network;
+
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import com.androidnetworking.AndroidNetworking;
+import com.androidnetworking.common.Priority;
+import com.androidnetworking.error.ANError;
+import com.androidnetworking.interceptors.HttpLoggingInterceptor;
+import com.androidnetworking.interfaces.ParsedRequestListener;
+import com.fazemeright.chatbotmetcs622.R;
+import com.fazemeright.chatbotmetcs622.network.handlers.NetworkCallback;
+import com.fazemeright.chatbotmetcs622.network.handlers.NetworkWrapper;
+import com.fazemeright.chatbotmetcs622.network.models.ChatBotError;
+import com.fazemeright.chatbotmetcs622.network.models.NetCompoundRes;
+import com.fazemeright.chatbotmetcs622.network.models.NetError;
+import com.fazemeright.chatbotmetcs622.network.models.NetResponse;
+import com.fazemeright.chatbotmetcs622.network.utils.CoreUtils;
+import com.google.gson.reflect.TypeToken;
+
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import timber.log.Timber;
+
+public class NetworkManager implements NetworkWrapper {
+
+ private final static String TAG = NetworkManager.class.getSimpleName();
+ private static final String CONTENT_TYPE = "application/json; charset=utf-8";
+ private static NetworkManager networkManager = null;
+
+ public static NetworkManager getInstance() {
+ if (networkManager == null) {
+ networkManager = new NetworkManager();
+ }
+ return networkManager;
+ }
+
+ /**
+ * To get Http client
+ *
+ * @param requestTimeOut Network Request timeout in millisecond it's configurable from backend
+ * @return OkHttpClient
+ */
+ public static OkHttpClient getHttpClient(int requestTimeOut) {
+ //if set < 2 second then we put our default timeout
+
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.connectTimeout(requestTimeOut, TimeUnit.SECONDS);
+ builder.readTimeout(requestTimeOut, TimeUnit.SECONDS);
+ builder.writeTimeout(requestTimeOut, TimeUnit.SECONDS);
+
+ return builder.build();
+ }
+
+ /**
+ * Initializing at the very first time
+ * Set Request Timeout
+ * Enabling network logging
+ *
+ * @param requestTimeOut Network Request timeout in millisecond it's configurable from backend
+ * @param context
+ */
+ public void init(Context context, int requestTimeOut) {
+ initSecureClient(context, requestTimeOut);
+ }
+
+ /**
+ * To initialize network manager
+ *
+ * @param context App context
+ * @param requestTimeOut Network Request timeout in millisecond it's configurable from backend
+ */
+ private void initSecureClient(Context context, int requestTimeOut) {
+ AndroidNetworking.initialize(context, getHttpClient(requestTimeOut));
+ }
+
+ @Override
+ public void makeGetRequest(Context context, String url, TypeToken typeToken, String tag,
+ final NetworkCallback networkCallback) {
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ printURLAndRequestParameters(url, null);
+ AndroidNetworking.get(url)
+ .setTag(tag)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ Timber.i("onResponse :: %s", CoreUtils.getStringFromObject(response));
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ Timber.e("onError :: %s", CoreUtils.getStringFromObject(anError));
+ networkCallback.onError(getNetError(anError, null));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), null));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+ @Override
+ public void makePostRequest(Context context, String url, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ final NetworkCallback networkCallback) {
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ AndroidNetworking.post(url)
+ .setContentType("application/x-www-form-urlencoded") // custom ContentType
+ .setTag(tag)
+ .addHeaders(hashMapHeader)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ networkCallback.onError(getNetError(anError, null));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context),
+ null));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+
+ @Override
+ public void makeGetRequestHeader(Context context, String url, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ final NetworkCallback networkCallback) {
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ printURLAndRequestParameters(url, null);
+ AndroidNetworking.get(url)
+ .setTag(tag)
+ .addHeaders(hashMapHeader)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ Timber.i("onResponse :: %s", CoreUtils.getStringFromObject(response));
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ Timber.e("onError :: %s", CoreUtils.getStringFromObject(anError));
+ networkCallback.onError(getNetError(anError, null));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), null));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+ @Override
+ public void makePutRequestHeader(Context context, String url, final Object dataObject,
+ TypeToken typeToken, HashMap hashMapHeader,
+ String tag, final NetworkCallback networkCallback) {
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ printURLAndRequestParameters(url, dataObject);
+ //.addBodyParameter(dataObject)
+ //.addStringBody(NetworkUtility.getStringFromObject(dataObject))
+ AndroidNetworking.put(url)
+ .addApplicationJsonBody(dataObject)
+ .addHeaders(hashMapHeader)
+ .setContentType(CONTENT_TYPE) // custom ContentType
+ .setTag(tag)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ // LogUtils.getInstance().printLog(TAG, "onResponse :: "
+ // + CoreUtils.getStringFromObject(response));
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ // LogUtils.getInstance().printLog(TAG, "onError :: "
+ // + CoreUtils.getStringFromObject(anError));
+ networkCallback.onError(getNetError(anError, dataObject));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), dataObject));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+
+ @Override
+ public void makePostRequest(Context context, String url, final Object dataObject, TypeToken typeToken,
+ String tag, final NetworkCallback networkCallback) {
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ printURLAndRequestParameters(url, dataObject);
+//.addBodyParameter(dataObject)
+//.addStringBody(NetworkUtility.getStringFromObject(dataObject))
+ AndroidNetworking.post(url)
+ .addApplicationJsonBody(dataObject)
+// .addHeaders(hashMapHeader)
+ .setContentType(CONTENT_TYPE) // custom ContentType
+ .setTag(tag)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ // LogUtils.getInstance().printLog(TAG, "onResponse :: "
+ // + CoreUtils.getStringFromObject(response));
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ // LogUtils.getInstance().printLog(TAG, "onError :: "
+ // + CoreUtils.getStringFromObject(anError));
+ networkCallback.onError(getNetError(anError, dataObject));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), dataObject));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+ @Override
+ public void makePostStringRequest(Context context, String url, String data, TypeToken typeToken,
+ String tag, NetworkCallback networkCallback) {
+
+ }
+
+ @Override
+ public NetCompoundRes makePostRequestSync(Context context, String url, Object dataObject,
+ TypeToken typeToken, String tag) {
+ return null;
+ }
+
+ @Override
+ public void makePostRequestHeader(Context context, String url, final Object dataObject,
+ TypeToken typeToken, HashMap hashMapHeader,
+ String tag, final NetworkCallback networkCallback) {
+
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ printURLAndRequestParameters(url, dataObject);
+//.addBodyParameter(dataObject)
+//.addStringBody(NetworkUtility.getStringFromObject(dataObject))
+ AndroidNetworking.post(url)
+ .addApplicationJsonBody(dataObject)
+ .addHeaders(hashMapHeader)
+ .setContentType(CONTENT_TYPE) // custom ContentType
+ .setTag(tag)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ // LogUtils.getInstance().printLog(TAG, "onResponse :: "
+ // + CoreUtils.getStringFromObject(response));
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ // LogUtils.getInstance().printLog(TAG, "onError :: "
+ // + CoreUtils.getStringFromObject(anError));
+ networkCallback.onError(getNetError(anError, dataObject));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), dataObject));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+ @Override
+ public void makeDeleteRequestHeader(Context context, String url, /*final Object dataObject,*/
+ TypeToken typeToken, HashMap hashMapHeader,
+ String tag, final NetworkCallback networkCallback) {
+
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+// printURLAndRequestParameters(url, dataObject);
+//.addBodyParameter(dataObject)
+//.addStringBody(NetworkUtility.getStringFromObject(dataObject))
+ AndroidNetworking.delete(url)
+// .addApplicationJsonBody(dataObject)
+ .addHeaders(hashMapHeader)
+ .setContentType(CONTENT_TYPE) // custom ContentType
+ .setTag(tag)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ // LogUtils.getInstance().printLog(TAG, "onResponse :: "
+ // + CoreUtils.getStringFromObject(response));
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ // LogUtils.getInstance().printLog(TAG, "onError :: "
+ // + CoreUtils.getStringFromObject(anError));
+ networkCallback.onError(getNetError(anError, null));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), null));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+ @Override
+ public void cancelRequest(String tag) {
+
+ }
+
+ /**
+ * To use only for get id_token,access_token and refresh_token when login with Social
+ *
+ * @param context
+ * @param url
+ * @param dataObject
+ * @param typeToken
+ * @param hashMapHeader
+ * @param tag
+ * @param networkCallback
+ * @param
+ */
+ @Override
+ public void makeCustomPostForSocialRequest(Context context, String url, final String dataObject,
+ TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ final NetworkCallback networkCallback) {
+
+ String stringURL = url.concat("?grant_type=authorization_code&redirect_uri=rosedaleapp://login&client_id=2idjeho7u7717nur0uhb6kmuhj&")
+ .concat("code=").concat(dataObject).concat("&scope=email openid profile");
+
+ if (CoreUtils.isValidUrl(url)) {
+ if (CoreUtils.isNetworkAvailable(context)) {
+ printURLAndRequestParameters(stringURL, dataObject);
+ AndroidNetworking.post(stringURL)
+ .setContentType("application/x-www-form-urlencoded") // custom ContentType
+ .setTag(tag)
+ .setPriority(Priority.MEDIUM)
+ .build()
+ .getAsParsed(typeToken, new ParsedRequestListener() {
+ @Override
+ public void onResponse(T response) {
+ NetResponse netResponse = new NetResponse();
+ netResponse.setResponse(response);
+ networkCallback.onSuccess(netResponse);
+ }
+
+ @Override
+ public void onError(ANError anError) {
+ networkCallback.onError(getNetError(anError, dataObject));
+ }
+ });
+ } else {
+ networkCallback.onError(getNetErrorConnectivityError(getConnectivityError(context), dataObject));
+ }
+ } else {
+ networkCallback.onError(getInvalidUrlError(url));
+ }
+ }
+
+ /**
+ * To create class for error from network/api
+ *
+ * @param anError
+ * @param requestObject
+ */
+ private NetError getNetError(ANError anError, @Nullable Object requestObject) {
+ NetError netError = new NetError(anError.getMessage());
+ netError.setErrorBody(anError.getErrorBody());
+ netError.setErrorCode(anError.getErrorCode());
+ netError.setErrorDetail(anError.getErrorDetail());
+ netError.setErrorLocalizeMessage(anError.getLocalizedMessage());
+ netError.setApiRequest(requestObject);
+ netError.setResponseErrorMessage(anError.getErrorBody());
+ return netError;
+ }
+
+ /**
+ * To create class for error from network/api
+ *
+ * @param anError
+ * @param requestObject
+ */
+ private NetError getNetErrorConnectivityError(ANError anError, @Nullable Object requestObject) {
+ NetError netError = new NetError(anError.getMessage());
+ netError.setErrorBody(anError.getErrorBody());
+ netError.setErrorCode(anError.getErrorCode());
+ netError.setErrorDetail(anError.getErrorDetail());
+ netError.setErrorLocalizeMessage(anError.getLocalizedMessage());
+ netError.setApiRequest(requestObject);
+ netError.setResponseErrorMessage(anError.getErrorBody());
+ return netError;
+ }
+
+ /**
+ * To get Connectivity Error
+ *
+ * @param context
+ * @return
+ */
+ private ANError getConnectivityError(Context context) {
+ ANError anError = new ANError(context.getString(R.string.no_internet_connection_available));
+ anError.setErrorCode(ChatBotError.ChatBotErrorCodes.INTERNET_NOT_AVAILABLE);
+ anError.setErrorBody(context.getString(R.string.no_internet_connection_available));
+ return anError;
+ }
+
+ /**
+ * To Print Request
+ *
+ * @param url
+ * @param data
+ */
+ private void printURLAndRequestParameters(String url, Object data) {
+ Timber.i("url :: %s", url);
+ Timber.i("requestParameters :: %s",
+ CoreUtils.getStringFromObject(data));
+ }
+
+
+ /**
+ * To get Invalid Url Error
+ *
+ * @param url
+ * @return
+ */
+ private NetError getInvalidUrlError(String url) {
+ NetError anError = new NetError("Invalid url: " + url);
+ anError.setErrorCode(ChatBotError.ChatBotErrorCodes.INVALID_URL);
+ return anError;
+ }
+
+
+ private void enableAndroidNetworkingLogging(boolean enable) {
+ if (enable) {
+ AndroidNetworking.enableLogging(HttpLoggingInterceptor.Level.BODY);
+ } else {
+ AndroidNetworking.enableLogging(HttpLoggingInterceptor.Level.NONE);
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/handlers/NetworkCallback.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/handlers/NetworkCallback.java
new file mode 100644
index 0000000..dac9c4e
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/handlers/NetworkCallback.java
@@ -0,0 +1,25 @@
+package com.fazemeright.chatbotmetcs622.network.handlers;
+
+
+import com.fazemeright.chatbotmetcs622.network.models.NetError;
+import com.fazemeright.chatbotmetcs622.network.models.NetResponse;
+
+/*
+ * Interface for handling API response
+ * */
+public interface NetworkCallback {
+
+ /**
+ * Interface method called on success of api call
+ *
+ * @param response {@link NetResponse}
+ */
+ void onSuccess(NetResponse response);
+
+ /**
+ * Interface method called on api/network failure
+ *
+ * @param error Error obj with error detail
+ */
+ void onError(NetError error);
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/handlers/NetworkWrapper.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/handlers/NetworkWrapper.java
new file mode 100644
index 0000000..bb2ea71
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/handlers/NetworkWrapper.java
@@ -0,0 +1,152 @@
+package com.fazemeright.chatbotmetcs622.network.handlers;
+
+
+import android.content.Context;
+
+import com.fazemeright.chatbotmetcs622.network.models.NetCompoundRes;
+import com.google.gson.reflect.TypeToken;
+
+import java.util.HashMap;
+
+/*
+ * Interface for calling API
+ * */
+public interface NetworkWrapper {
+
+ /**
+ * API GET method Request
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makeGetRequest(Context context, String url, TypeToken typeToken, String tag,
+ NetworkCallback networkCallback);
+
+ /**
+ * API POST method Request
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makePostRequest(Context context, String url, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ NetworkCallback networkCallback);
+
+ /**
+ * API POST method Request
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param dataObject Request body
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makePostRequest(Context context, String url, Object dataObject, TypeToken typeToken,
+ String tag, NetworkCallback networkCallback);
+
+ /**
+ * API POST method Request
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param data Request body
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makePostStringRequest(Context context, String url, String data, TypeToken typeToken,
+ String tag, NetworkCallback networkCallback);
+
+ /**
+ * API sync POST method Request. Expect a response/error in {@link NetCompoundRes}
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param dataObject Request body
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param tag request tag
+ * @return Compound response ( It contains success / error ). First check it using method
+ * isSuccess() to find whether response contains error or not
+ */
+ NetCompoundRes makePostRequestSync(Context context, String url, Object dataObject,
+ TypeToken typeToken, String tag);
+
+ /**
+ * API POST method Request with header
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param dataObject Request body
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param hashMapHeader HashMap of request header
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makePostRequestHeader(Context context, String url, Object dataObject, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ NetworkCallback networkCallback);
+
+ /**
+ * API POST method Request with header
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param hashMapHeader HashMap of request header
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makeDeleteRequestHeader(Context context, String url/*, Object dataObject*/, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ NetworkCallback networkCallback);
+
+
+ /**
+ * API Get method Request with header
+ *
+ * @param context App context
+ * @param url Request URL
+ * @param typeToken {@link TypeToken} of the expected parsed object
+ * @param hashMapHeader HashMap of request header
+ * @param tag request tag
+ * @param networkCallback Network callback
+ */
+ void makeGetRequestHeader(Context context, String url, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ NetworkCallback networkCallback);
+
+ /**
+ * API PUT Method Request with header
+ *
+ * @param context
+ * @param url
+ * @param dataObject
+ * @param typeToken
+ * @param hashMapHeader
+ * @param tag
+ * @param networkCallback
+ * @param
+ */
+ void makePutRequestHeader(Context context, String url, Object dataObject, TypeToken typeToken,
+ HashMap hashMapHeader, String tag,
+ NetworkCallback networkCallback);
+
+ /**
+ * Cancel api request by tag
+ *
+ * @param tag request tag
+ */
+ void cancelRequest(String tag);
+
+ void makeCustomPostForSocialRequest(Context context, String url,
+ String dataObject, TypeToken typeToken,
+ HashMap hashMapAuthenticate, String s,
+ NetworkCallback networkCallback);
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/ChatBotError.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/ChatBotError.java
new file mode 100644
index 0000000..4e525c6
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/ChatBotError.java
@@ -0,0 +1,60 @@
+package com.fazemeright.chatbotmetcs622.network.models;
+
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+
+public class ChatBotError {
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ChatBotErrorCodes.INTERNET_NOT_AVAILABLE, /*SOMETHING_WENT_WRONG,*/ ChatBotErrorCodes.INVALID_URL, ChatBotErrorCodes.DATA_NOT_FOUND, ChatBotErrorCodes.BAD_REQUEST, ChatBotErrorCodes.UN_AUTHORIZED, ChatBotErrorCodes.UN_EXPECTED_SERVER_ERROR})
+ public @interface ChatBotErrorCodes {
+
+ /**
+ * Internet is not available
+ */
+ public static final int INTERNET_NOT_AVAILABLE = 1001;
+
+
+ /**
+ * Invalid URL
+ */
+ public static final int INVALID_URL = 1002;
+
+
+ /**
+ * Used for unknown error
+ */
+
+ public static final int SOMETHING_WENT_WRONG = -123456;
+
+ /**
+ * Used for data not found error
+ */
+ public static final int DATA_NOT_FOUND = 204;
+
+
+ /**
+ * Used for Bad request (Malformed Parameters or parameters missing)
+ */
+ public static final int BAD_REQUEST = 400;
+
+
+ /**
+ * Used for Unauthorized (Authorization header is incorrec, log-in user again)
+ */
+ public static final int UN_AUTHORIZED = 401;
+
+
+ /**
+ * Used for Unexpected server error (Error)
+ */
+ public static final int UN_EXPECTED_SERVER_ERROR = 500;
+
+ }
+
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetCompoundRes.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetCompoundRes.java
new file mode 100644
index 0000000..33867a1
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetCompoundRes.java
@@ -0,0 +1,37 @@
+package com.fazemeright.chatbotmetcs622.network.models;
+
+/**
+ * To use when we want to have sync response from network manager
+ *
+ * @param
+ */
+public class NetCompoundRes {
+
+ private boolean isSuccess;
+ private NetResponse netResponse;
+ private NetError netError;
+
+ public void setSuccess(boolean success) {
+ isSuccess = success;
+ }
+
+ public void setNetResponse(NetResponse netResponse) {
+ this.netResponse = netResponse;
+ }
+
+ public void setNetError(NetError netError) {
+ this.netError = netError;
+ }
+
+ public boolean isSuccess() {
+ return isSuccess;
+ }
+
+ public NetResponse getNetResponse() {
+ return netResponse;
+ }
+
+ public NetError getNetError() {
+ return netError;
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetError.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetError.java
new file mode 100644
index 0000000..7e00820
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetError.java
@@ -0,0 +1,114 @@
+package com.fazemeright.chatbotmetcs622.network.models;
+
+
+import android.text.TextUtils;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/*
+ * Class for handling Network/API related errors
+ * */
+public class NetError extends Exception {
+
+ private String errorBody = "";
+ private int errorCode = ChatBotError.ChatBotErrorCodes.SOMETHING_WENT_WRONG;
+ private String errorDetail = "";
+ private String errorLocalizeMessage = "";
+ private Object apiRequest;
+ private String requestName = "";
+ private String responseErrorMessage;
+
+ public String getResponseErrorMessage() {
+ return responseErrorMessage;
+ }
+
+ public void setResponseErrorMessage(String responseErrorMessage) {
+ this.responseErrorMessage = parseJson(responseErrorMessage);
+ }
+
+ private String parseJson(String responseErrorMessage) {
+ String errorMessage = "Something went wrong!";
+ if (!TextUtils.isEmpty(responseErrorMessage)) {
+ try {
+ JSONObject jsonObject = new JSONObject(responseErrorMessage);
+ if (jsonObject.has("responseMessage")) {
+ errorMessage = jsonObject.getString("responseMessage");
+ } else {
+ return responseErrorMessage;
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ return responseErrorMessage;
+ }
+ }
+ return errorMessage;
+
+ }
+
+ public String getRequestName() {
+ return requestName;
+ }
+
+ public void setRequestName(String requestName) {
+ if (requestName != null) {
+ this.requestName = requestName;
+ }
+ }
+
+ public Object getApiRequest() {
+ return apiRequest;
+ }
+
+ public void setApiRequest(Object apiRequest) {
+ this.apiRequest = apiRequest;
+ }
+
+ public String getErrorLocalizeMessage() {
+ return errorLocalizeMessage;
+ }
+
+ public void setErrorLocalizeMessage(String errorLocalizeMessage) {
+ if (errorLocalizeMessage != null) {
+ this.errorLocalizeMessage = errorLocalizeMessage;
+ }
+ }
+
+ public NetError(String message) {
+ super(message);
+ if (message == null) {
+ message = "Getting null error message.";
+ }
+ setErrorLocalizeMessage(message);
+ setErrorBody(message);
+ setErrorDetail(message);
+ }
+
+ public void setErrorDetail(String errorDetail) {
+ if (errorDetail != null) {
+ this.errorDetail = errorDetail;
+ }
+ }
+
+ public String getErrorDetail() {
+ return this.errorDetail;
+ }
+
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return this.errorCode;
+ }
+
+ public String getErrorBody() {
+ return errorBody;
+ }
+
+ public void setErrorBody(String errorBody) {
+ if (errorBody != null) {
+ this.errorBody = errorBody;
+ }
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetResponse.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetResponse.java
new file mode 100644
index 0000000..3ad6b07
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/NetResponse.java
@@ -0,0 +1,20 @@
+package com.fazemeright.chatbotmetcs622.network.models;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Class for handling generic response
+ */
+public class NetResponse {
+
+ @SerializedName("response")
+ private T response;
+
+ public T getResponse() {
+ return response;
+ }
+
+ public void setResponse(T response) {
+ this.response = response;
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/request/MessageQueryRequestModel.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/request/MessageQueryRequestModel.java
new file mode 100644
index 0000000..85d8bb9
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/request/MessageQueryRequestModel.java
@@ -0,0 +1,22 @@
+package com.fazemeright.chatbotmetcs622.network.models.request;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class MessageQueryRequestModel {
+ @SerializedName("query")
+ @Expose
+ private String query;
+
+ public MessageQueryRequestModel(String query) {
+ this.query = query;
+ }
+
+ public String getQuery() {
+ return query;
+ }
+
+ public void setQuery(String query) {
+ this.query = query;
+ }
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/response/QueryResponseMessage.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/response/QueryResponseMessage.java
new file mode 100644
index 0000000..93077ad
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/models/response/QueryResponseMessage.java
@@ -0,0 +1,36 @@
+package com.fazemeright.chatbotmetcs622.network.models.response;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class QueryResponseMessage {
+
+ @SerializedName("data")
+ @Expose
+ private Data data;
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+
+ public class Data {
+
+
+ @SerializedName("responseMsg")
+ @Expose
+ private String responseMsg;
+
+ public String getResponseMsg() {
+ return responseMsg;
+ }
+
+ public void setResponseMsg(String responseMsg) {
+ this.responseMsg = responseMsg;
+ }
+ }
+}
+
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/network/utils/CoreUtils.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/utils/CoreUtils.java
new file mode 100644
index 0000000..c34cf18
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/network/utils/CoreUtils.java
@@ -0,0 +1,43 @@
+package com.fazemeright.chatbotmetcs622.network.utils;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.webkit.URLUtil;
+
+import com.google.gson.Gson;
+
+
+public class CoreUtils {
+
+ /**
+ * To check internet connection
+ *
+ * @param mContext App context
+ * @return true if available else false
+ */
+ public static boolean isNetworkAvailable(Context mContext) {
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = null;
+ if (cm != null) {
+ networkInfo = cm.getActiveNetworkInfo();
+ }
+ return networkInfo != null && networkInfo.isConnected();
+ }
+
+ public static String getStringFromObject(Object data) {
+ Gson gson = new Gson();
+ return gson.toJson(data);
+ }
+
+ /**
+ * Check whether URL is valid or not
+ *
+ * @param url url
+ * @return true if valid else false
+ */
+ public static boolean isValidUrl(String url) {
+ return URLUtil.isValidUrl(url);
+ }
+
+}
diff --git a/app/src/main/java/com/fazemeright/chatbotmetcs622/repositories/MessageRepository.java b/app/src/main/java/com/fazemeright/chatbotmetcs622/repositories/MessageRepository.java
new file mode 100644
index 0000000..4961091
--- /dev/null
+++ b/app/src/main/java/com/fazemeright/chatbotmetcs622/repositories/MessageRepository.java
@@ -0,0 +1,427 @@
+package com.fazemeright.chatbotmetcs622.repositories;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Build;
+
+import androidx.core.content.ContextCompat;
+
+import com.fazemeright.chatbotmetcs622.database.ChatBotDatabase;
+import com.fazemeright.chatbotmetcs622.database.messages.Message;
+import com.fazemeright.chatbotmetcs622.database.messages.MessageDao;
+import com.fazemeright.chatbotmetcs622.intentservice.FireBaseIntentService;
+import com.fazemeright.chatbotmetcs622.models.ChatRoom;
+import com.fazemeright.chatbotmetcs622.network.ApiManager;
+import com.fazemeright.chatbotmetcs622.network.NetworkManager;
+import com.fazemeright.chatbotmetcs622.network.handlers.NetworkCallback;
+import com.fazemeright.chatbotmetcs622.network.models.NetError;
+import com.fazemeright.chatbotmetcs622.network.models.NetResponse;
+import com.fazemeright.chatbotmetcs622.network.models.response.QueryResponseMessage;
+import com.fazemeright.firebase_api_library.api.FireBaseApiManager;
+import com.fazemeright.firebase_api_library.listeners.DBValueListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import timber.log.Timber;
+
+
+public class MessageRepository {
+
+ private static MessageRepository repository;
+ private ChatBotDatabase database;
+ private ApiManager apiManager;
+ private FireBaseApiManager fireBaseApiManager;
+
+ private MessageRepository(ChatBotDatabase database, ApiManager apiManager, FireBaseApiManager fireBaseApiManager) {
+ this.database = database;
+ this.apiManager = apiManager;
+ this.fireBaseApiManager = fireBaseApiManager;
+// messageList = this.database.messageDao().getAllMessages();
+ }
+
+ /**
+ * Call to get instance of MessageRepository with the given context
+ *
+ * @param context given context
+ * @return synchronized call to get Instance of MessageRepository class
+ */
+ public static MessageRepository getInstance(Context context) {
+ if (repository == null) {
+ synchronized (MessageRepository.class) {
+// get instance of database
+ ChatBotDatabase database = ChatBotDatabase.getInstance(context);
+ ApiManager apiManager = ApiManager.getInstance();
+ FireBaseApiManager fireBaseApiManager = FireBaseApiManager.getInstance();
+ apiManager.init(NetworkManager.getInstance());
+ repository = new MessageRepository(database, apiManager, fireBaseApiManager);
+ }
+ }
+ return repository;
+ }
+
+ /**
+ * Call to insert given project into database with thread safety
+ *
+ * @param newMessage given project
+ * @return
+ */
+ private Message insertMessageInRoom(Message newMessage) {
+// insert into Room using AsyncTask
+ Timber.i("Insert message in Room called%s", newMessage.getMsg());
+ try {
+ return new InsertAsyncTask(database.messageDao()).execute(newMessage).get();
+ } catch (ExecutionException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ return newMessage;
+ }
+
+ /**
+ * Call to update given project into database with thread safety
+ *
+ * @param oldMessage given project
+ */
+ private void updateMessage(Message oldMessage) {
+ // insert into Room using AsyncTask
+ new UpdateAsyncTask(database.messageDao()).execute(oldMessage);
+ }
+
+ /**
+ * Call to get Message with given Message ID
+ *
+ * @param mid given Message ID
+ * @return Message with given ID
+ */
+ public Message getMessage(long mid) {
+ return fetchMessage(mid);
+ }
+
+ /**
+ * Call to get Message with given Message ID with thread safety
+ *
+ * @param pid given Message ID
+ * @return Message with given ID
+ */
+ private Message fetchMessage(long pid) {
+ try {
+ return new FetchMessageAsyncTask(database.messageDao()).execute(pid).get();
+ } catch (ExecutionException | InterruptedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Call to delete project with given project
+ *
+ * @param project given Message
+ * @return Deleted Message
+ */
+ public void deleteMessage(Message project) {
+ deleteMessageFromRoom(project);
+ }
+
+ /**
+ * Delete given Message from Room with Thread Safety
+ *
+ * @param project given Message
+ */
+ private void deleteMessageFromRoom(Message project) {
+ try {
+ new DeleteMessageAsyncTask(database.messageDao()).execute(project).get();
+ } catch (ExecutionException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public ArrayList getMessagesForChatRoom(ChatRoom chatRoom) {
+ return getChatRoomMessagesFromDatabase(chatRoom);
+ }
+
+ private ArrayList getChatRoomMessagesFromDatabase(ChatRoom chatRoom) {
+ try {
+ return (ArrayList) new FetchChatRoomMessagesAsyncTask(database.messageDao()).execute(chatRoom).get();
+ } catch (ExecutionException | InterruptedException e) {
+ e.printStackTrace();
+ return new ArrayList<>();
+ }
+ }
+
+ /**
+ * Called when user sends a given new message in the ChatRoom
+ * - Add new Message to Room
+ * - Call API to fetch answer for new message
+ * - Sync message with FireStore
+ *
+ * @param newMessage given new message
+ */
+ public void newMessageSent(final Context context, final Message newMessage, final OnMessageResponseReceivedListener listener) {
+ final Message roomLastMessage = insertMessageInRoom(newMessage);
+ insertMessageInFireBase(context, roomLastMessage);
+ apiManager.queryDatabase(context, newMessage, new NetworkCallback() {
+ @Override
+ public void onSuccess(NetResponse response) {
+ Message queryResponseMessage = Message.newMessage(response.getResponse().getData().getResponseMsg(),
+ newMessage.getReceiver(), newMessage.getSender(), newMessage.getChatRoomId());
+
+ Message roomLastInsertedMessage = insertMessageInRoom(queryResponseMessage);
+ insertMessageInFireBase(context, roomLastInsertedMessage);
+ listener.onMessageResponseReceived(queryResponseMessage);
+ }
+
+ @Override
+ public void onError(NetError error) {
+ listener.onNoResponseReceived(new Error(error.getErrorLocalizeMessage()));
+ }
+ });
+
+// TODO: Finish the remaining cart
+ }
+
+ /**
+ * Call to insert the given new message to FireStore database
+ *
+ * @param context context
+ * @param newMessage given new message
+ */
+ private void insertMessageInFireBase(Context context, Message newMessage) {
+ Intent intent = new Intent(context, FireBaseIntentService.class);
+ intent.putExtra(FireBaseIntentService.ACTION, FireBaseIntentService.ACTION_ADD_MESSAGE);
+ intent.putExtra(FireBaseIntentService.MESSAGE, newMessage);
+ context.startService(intent);
+ }
+
+ public ArrayList getAllMessages() {
+ return (ArrayList) database.messageDao().getAllMessages();
+ }
+
+ /**
+ * Clear all given chat room messages
+ * - From Room
+ * - From FireStore
+ *
+ * @param chatRoom given chat room
+ */
+ public void clearAllChatRoomMessages(ChatRoom chatRoom) {
+ clearAllChatRoomMessagesFromRoom(chatRoom);
+ }
+
+ private void clearAllChatRoomMessagesFromRoom(ChatRoom chatRoom) {
+ new ClearAllMessagesInChatRoomAsyncTask(database.messageDao()).execute(chatRoom);
+ }
+
+ /**
+ * Call to logout user and clear all messages from Room
+ */
+ public void logOutUser() {
+ fireBaseApiManager.logOutUser();
+ clearAllMessages();
+ }
+
+ /**
+ * Call to clear all messages from Room
+ */
+ private void clearAllMessages() {
+ new ClearAllMessagesAsyncTask(database.messageDao()).execute();
+ }
+
+ /**
+ * Add given list of messages to Room
+ *
+ * @param messages
+ */
+ public void addMessages(List messages) {
+ new AddAllMessagesAsyncTask(database.messageDao()).execute(messages);
+ }
+
+ /**
+ * Call to add the given message to FireStore
+ *
+ * @param messageHashMap given message converted into HashMap
+ */
+ public void addMessageToFireBase(Map messageHashMap) {
+ fireBaseApiManager.addMessageToUserDatabase(messageHashMap);
+ }
+
+ /**
+ * Call to sync messages from FireStore to Room for the logged in user
+ */
+ public void syncMessagesFromFireStoreToRoom() {
+ fireBaseApiManager.syncMessages(new DBValueListener>>() {
+ @Override
+ public void onDataReceived(List