ids = new ObjectContainer<>(fieldsToCreate);
+ for (int i = 0; i < fieldsToCreate; i++) {
+ long id = mFSetOperations.registerNewField(mId, "field#" + i, false);
+ ids.storeObject(id);
+ }
+ Log.d(TAG, ids.toString());
+ getAllFields();
+ ids.forEach(id -> {
+ mFSetOperations.updateFieldCode(id, "updatedField#" + id);
+ mFSetOperations.updateFieldCodeBeenUsed(id, (Math.random() > Math.random()));
+ });
+ mFSetOperations.apply();
+ sleep(1000);
+ getAllFields();
+ ids.forEach(id -> mFSetOperations.removeField(id));
+ getAllFields();
+ }
+
+ @After
+ public void finish() {
+ mOperations.finishConnection();
+ mFields.finishConnection();
+ }
+
+ private void getAllSecurityCodes() {
+ Log.i(TAG, mGetOperations.getAllSecurityCodes().toString());
+ }
+
+ private void getAllFields() {
+ Log.i(TAG, mFGetOperations.getAllFields().toString());
+ }
+}
diff --git a/SecurePass/app/src/androidTest/java/javinator9889/securepass/keystore/PasswordWorker.java b/SecurePass/app/src/androidTest/java/javinator9889/securepass/keystore/PasswordWorker.java
new file mode 100644
index 0000000..bb4d1ef
--- /dev/null
+++ b/SecurePass/app/src/androidTest/java/javinator9889/securepass/keystore/PasswordWorker.java
@@ -0,0 +1,57 @@
+package javinator9889.securepass.keystore;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.UnrecoverableEntryException;
+import java.util.Arrays;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import javinator9889.securepass.util.cipher.keystore.IPasswordCipher;
+import javinator9889.securepass.util.cipher.keystore.PasswordCipher;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 11/11/2018 - APP.
+ */
+public class PasswordWorker {
+ private IPasswordCipher mCipher;
+
+ @Before
+ public void setup() throws KeyStoreException, InvalidAlgorithmParameterException {
+ mCipher = new PasswordCipher(InstrumentationRegistry.getInstrumentation()
+ .getTargetContext(), "test");
+ mCipher.createNewKeys();
+ }
+
+ @Test
+ public void test() throws UnrecoverableEntryException, InvalidKeyException {
+ String password = "passwordToBeEncryptedUsingRSAAndPasswordCipher";
+ System.out.println("Password: " + password);
+ byte[] cipheredPassword = mCipher.encryptPassword(password.getBytes());
+ System.out.println("Ciphered & signed password: \n\n" + Arrays.toString(cipheredPassword));
+ String recoveredPassword = mCipher.decryptPassword(cipheredPassword);
+ System.out.println("Recovered password: " + recoveredPassword);
+ }
+
+ @After
+ public void finalizeTest() {
+ mCipher.deleteKey();
+ }
+}
diff --git a/APP/app/src/main/AndroidManifest.xml b/SecurePass/app/src/main/AndroidManifest.xml
similarity index 92%
rename from APP/app/src/main/AndroidManifest.xml
rename to SecurePass/app/src/main/AndroidManifest.xml
index b6ee995..71843f5 100644
--- a/APP/app/src/main/AndroidManifest.xml
+++ b/SecurePass/app/src/main/AndroidManifest.xml
@@ -1,35 +1,33 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/APP/app/src/androidTest/java/javinator9889/securepass/DataClassForTests.java b/SecurePass/app/src/main/java/javinator9889/securepass/DataClassForTests.java
similarity index 97%
rename from APP/app/src/androidTest/java/javinator9889/securepass/DataClassForTests.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/DataClassForTests.java
index f356f9e..41c0d00 100644
--- a/APP/app/src/androidTest/java/javinator9889/securepass/DataClassForTests.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/DataClassForTests.java
@@ -1,62 +1,62 @@
-package javinator9889.securepass;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javinator9889.securepass.data.container.ClassContainer;
-import javinator9889.securepass.data.entry.Category;
-import javinator9889.securepass.data.entry.Entry;
-import javinator9889.securepass.data.entry.QRCode;
-import javinator9889.securepass.data.secret.Field;
-import javinator9889.securepass.data.secret.SecurityCode;
-
-/**
- * Created by Javinator9889 on 21/04/2018.
- */
-public class DataClassForTests {
- // DO NOT LET ANYONE INIT THIS CLASS
- private DataClassForTests(){}
-
-// public static ClassContainer CONTAINER_TEST_CLASS() {
-// ClassContainer container = new ClassContainer();
-// List categories = new ArrayList<>();
-// List entries = new ArrayList<>();
-// List qrCodes = new ArrayList<>();
-// List fields = new ArrayList<>();
-// List securityCodes = new ArrayList<>();
-// Map preferences = new HashMap<>();
-//
-// categories.add(new Category(1, "Category_1"));
-// categories.add(new Category(2, "Category_2"));
-//
-// entries.add(new Entry(1, "Account_1", "password_1",
-// "icon_1", "description_1", new Category()));
-// entries.add(new Entry(2, "Account_2", "password_2",
-// "icon_2", "description_2", new Category()));
-//
-// qrCodes.add(new QRCode(1, "qrcode_1", "description_1", "qrdata",
-// entries.get(0)));
-// qrCodes.add(new QRCode(2, "qrcode_2", "description_2", "qrdata2",
-// entries.get(1)));
-//
-// fields.add(new Field(1, "field_1", false,
-// new SecurityCode(1, "account_1")));
-// fields.add(new Field(2, "field_2", true,
-// new SecurityCode(2, "account_2")));
-//
-// securityCodes.add(new SecurityCode(1, "account_1"));
-// securityCodes.add(new SecurityCode(2, "account_2"));
-//
-// preferences.put("test_val", true);
-//
-// container.setCategories(categories);
-// container.setEntries(entries);
-// container.setQrCodes(qrCodes);
-// container.setFields(fields);
-// container.setSecurityCodes(securityCodes);
-// container.setUserSharedPreferences(preferences);
-// return container;
-// }
-}
+package javinator9889.securepass;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javinator9889.securepass.data.container.ClassContainer;
+import javinator9889.securepass.data.entry.Category;
+import javinator9889.securepass.data.entry.Entry;
+import javinator9889.securepass.data.entry.QRCode;
+import javinator9889.securepass.data.secret.Field;
+import javinator9889.securepass.data.secret.SecurityCode;
+
+/**
+ * Created by Javinator9889 on 21/04/2018.
+ */
+public class DataClassForTests {
+ // DO NOT LET ANYONE INIT THIS CLASS
+ private DataClassForTests(){}
+
+// public static ClassContainer CONTAINER_TEST_CLASS() {
+// ClassContainer container = new ClassContainer();
+// List categories = new ArrayList<>();
+// List entries = new ArrayList<>();
+// List qrCodes = new ArrayList<>();
+// List fields = new ArrayList<>();
+// List securityCodes = new ArrayList<>();
+// Map preferences = new HashMap<>();
+//
+// categories.add(new Category(1, "Category_1"));
+// categories.add(new Category(2, "Category_2"));
+//
+// entries.add(new Entry(1, "Account_1", "password_1",
+// "icon_1", "description_1", new Category()));
+// entries.add(new Entry(2, "Account_2", "password_2",
+// "icon_2", "description_2", new Category()));
+//
+// qrCodes.add(new QRCode(1, "qrcode_1", "description_1", "qrdata",
+// entries.get(0)));
+// qrCodes.add(new QRCode(2, "qrcode_2", "description_2", "qrdata2",
+// entries.get(1)));
+//
+// fields.add(new Field(1, "field_1", false,
+// new SecurityCode(1, "account_1")));
+// fields.add(new Field(2, "field_2", true,
+// new SecurityCode(2, "account_2")));
+//
+// securityCodes.add(new SecurityCode(1, "account_1"));
+// securityCodes.add(new SecurityCode(2, "account_2"));
+//
+// preferences.put("test_val", true);
+//
+// container.setCategories(categories);
+// container.setEntries(entries);
+// container.setQrCodes(qrCodes);
+// container.setFields(fields);
+// container.setSecurityCodes(securityCodes);
+// container.setUserSharedPreferences(preferences);
+// return container;
+// }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/Generator.java b/SecurePass/app/src/main/java/javinator9889/securepass/Generator.java
new file mode 100644
index 0000000..deaeaa9
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/Generator.java
@@ -0,0 +1,145 @@
+package javinator9889.securepass;
+
+import com.github.javinator9889.exporter.FileToBytesExporter;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+import com.lambdaworks.crypto.SCryptUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.Arrays;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.util.scrypt.Scrypt;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 05/11/2018 - APP.
+ */
+public class Generator {
+ private static final String SIGNATURE = "SHA256withRSA";
+ /**
+ * Do not let anyone use this class
+ */
+ private Generator() {}
+
+ /**
+ * Generates a bytes file from given file.
+ *
+ * @param args {@code String[]} containing, at 0: "filename"; at 1: output file path.
+ * @throws IOException when an error occurs (see {@link FileToBytesExporter#readSource()} &
+ * {@link FileToBytesExporter#writeObject(File)}).
+ */
+ public static void main(String[] args) throws Exception {
+ exportDB();
+ /*if (args.length <= 1)
+ throw new IllegalArgumentException("At least two arguments must be included " +
+ "(filename & output file)");
+ FileToBytesExporter exporter = new FileToBytesExporter(args[0]);
+ exporter.readSource(true);
+ exporter.writeObject(new File(args[1]));*/
+ /*String ANDROID_KEY_STORE = "AndroidKeyStore";
+ String ALGORITHM_RSA = "RSA";
+ KeyPair keyPair;
+ KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM_RSA);
+ generator.initialize(2048, new SecureRandom());
+ keyPair = generator.generateKeyPair();
+ String data = "hola1234";
+ byte[] s = sign(data, keyPair.getPrivate());
+ System.out.println(Arrays.toString(s));
+ System.out.println(verifySignature(s, keyPair.getPublic()));
+ System.out.println(new String(s));*/
+ String password = "ThisIsAPassword";
+ /*byte[] bytesPass = password.getBytes(StandardCharsets.UTF_8);
+ SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+ for (int n = 14; n < 22; ++n) {
+ long startTime = System.currentTimeMillis();
+ SCrypt.scrypt(bytesPass, salt, 1 << n, 8, 1, 32);
+ long endTime = System.currentTimeMillis();
+ long ms = (endTime - startTime);
+ System.out.printf("N = 2^%d\t%d ms\n", n, ms);
+ }*/
+ /*int N = 1 << 15;
+ System.out.println(N);
+ Scrypt scryptUtil = new Scrypt();
+ scryptUtil.scrypt(password);
+ String scryptUtilHash = scryptUtil.getHash();
+ byte[] key = scryptUtil.getKey();
+// byte[] key = SCrypt.scrypt(password.getBytes(StandardCharsets.UTF_8), salt, N, 8, 4, 32);
+ System.out.println(Arrays.toString(key));
+ System.out.println(key.length);
+ System.out.println(key.length * 8);
+ System.out.println(scryptUtilHash);
+ Scrypt checker = new Scrypt(scryptUtilHash);
+ System.out.println(checker.check(password));
+ for (int i = 0; i < 10; ++i) {
+ String scrypt = SCryptUtil.scrypt(password, N, 8, 4);
+ System.out.println(scrypt);
+ boolean validate = SCryptUtil.check(password, scrypt);
+ System.out.println(validate);
+// System.out.println(Arrays.toString(scrypt.getBytes()));
+// System.out.println(scrypt.getBytes().length);
+ }
+ HashCode hash = Hashing.sha256().hashString(password, StandardCharsets.UTF_8);
+ System.out.println(hash.toString());
+ System.out.println(Arrays.toString(hash.asBytes()));
+ System.out.println(hash.asBytes().length);
+ System.out.println(hash.asBytes().length * 8);
+ System.out.println(hash.bits());*/
+ }
+
+ private static byte[] sign(@NonNull String data, @NonNull PrivateKey privateKeyEntry)
+ throws InvalidKeyException, SignatureException {
+ try {
+ Signature signature = Signature.getInstance(SIGNATURE);
+ signature.initSign(privateKeyEntry);
+ signature.update(data.getBytes());
+ return signature.sign();
+ } catch (NoSuchAlgorithmException ignored) {
+ return null;
+ }
+ }
+
+ private static boolean verifySignature(@NonNull byte[] data, @NonNull PublicKey
+ privateKeyEntry) throws Exception {
+ Signature s = Signature.getInstance(SIGNATURE);
+ s.initVerify(privateKeyEntry);
+ s.update(data);
+ return s.verify(data);
+ }
+
+ private static void exportDB() throws Exception {
+ String path = "D:\\\\\\Nextcloud\\AndroidApps\\SecurePass\\APP\\app\\src\\main\\res" +
+ "\\raw\\";
+ String source = "database_script_readable.sql";
+ String dest = "database_scriptabase_script.osql";
+// FileToBytesExporter exporter = new FileToBytesExporter(source, path);
+// exporter.readSource(true);
+// exporter.writeObject(new File(path + dest));
+ String data = FileToBytesExporter.readSource(new File(path, source));
+ FileToBytesExporter.writeObject(data, new File(path, dest));
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/SecurePass.java b/SecurePass/app/src/main/java/javinator9889/securepass/SecurePass.java
similarity index 85%
rename from APP/app/src/main/java/javinator9889/securepass/SecurePass.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/SecurePass.java
index 732cd3a..4bcbbfc 100644
--- a/APP/app/src/main/java/javinator9889/securepass/SecurePass.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/SecurePass.java
@@ -1,35 +1,38 @@
-package javinator9889.securepass;
-
-import android.app.Application;
-
-import com.chamber.java.library.SharedChamber;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.util.resources.PreferencesManager;
-
-/**
- * Created by Javinator9889 on 25/03/2018.
- * Main application - class with different parameters useful for app packages
- */
-
-public class SecurePass extends Application {
- private static SecurePass APPLICATION_INSTANCE;
- //private Context applicationContext;
-
- @NonNull
- public static SecurePass getApplicationInstance() {
- return APPLICATION_INSTANCE;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- APPLICATION_INSTANCE = this;
- PreferencesManager.instantiate(this);
- SharedChamber.initChamber(this);
- }
-
- public static int getNumberOfProcessors() {
- return Runtime.getRuntime().availableProcessors();
- }
-}
+package javinator9889.securepass;
+
+import android.app.Application;
+
+import com.chamber.java.library.SharedChamber;
+
+import org.jetbrains.annotations.Contract;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.util.resources.PreferencesManager;
+
+/**
+ * Created by Javinator9889 on 25/03/2018.
+ * Main application - class with different parameters useful for app packages
+ */
+
+public class SecurePass extends Application {
+ private static SecurePass APPLICATION_INSTANCE;
+ //private Context applicationContext;
+
+ @Contract(pure = true)
+ @NonNull
+ public static SecurePass getApplicationInstance() {
+ return APPLICATION_INSTANCE;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ APPLICATION_INSTANCE = this;
+ PreferencesManager.instantiate(this);
+// SharedChamber.initChamber(this);
+ }
+
+ public static int getNumberOfProcessors() {
+ return Runtime.getRuntime().availableProcessors();
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/BackupManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/BackupManager.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/backup/BackupManager.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/BackupManager.java
index 8a6e258..809f8ba 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/BackupManager.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/BackupManager.java
@@ -1,56 +1,56 @@
-package javinator9889.securepass.backup;
-
-import android.app.Activity;
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.backup.drive.DriveDownloader;
-import javinator9889.securepass.backup.drive.DriveUploader;
-import javinator9889.securepass.backup.drive.IDriveDownloader;
-import javinator9889.securepass.backup.drive.IDriveUploader;
-
-/**
- * Class for managing backups
- * Created by Javinator9889 on 06/04/2018.
- */
-public class BackupManager implements IBackup {
- private IDriveUploader mUploader;
- private IDriveDownloader mDownloader;
-
- /**
- * Public constructor for managing backups
- *
- * @param backupContext Context
when instantiating this class
- * @param sourceActivity Activity
when instantiating this class
- * @see Activity
- * @see Context
- * @see DriveUploader
- * @see DriveDownloader
- */
- public BackupManager(@NonNull Context backupContext, @NonNull Activity sourceActivity) {
- this.mUploader = new DriveUploader(backupContext, sourceActivity);
- this.mDownloader = new DriveDownloader(backupContext, sourceActivity);
- }
-
- /**
- * Does the backup by using
- * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class
- *
- * @see javinator9889.securepass.backup.drive.IDriveUploader
- */
- @Override
- public void doBackup() {
- this.mUploader.uploadDatabase();
- }
-
- /**
- * Restores the backup by using
- * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
- *
- * @see javinator9889.securepass.backup.drive.IDriveDownloader
- */
- @Override
- public void restoreBackup() {
-
- }
-}
+package javinator9889.securepass.backup;
+
+import android.app.Activity;
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.backup.drive.DriveDownloader;
+import javinator9889.securepass.backup.drive.DriveUploader;
+import javinator9889.securepass.backup.drive.IDriveDownloader;
+import javinator9889.securepass.backup.drive.IDriveUploader;
+
+/**
+ * Class for managing backups
+ * Created by Javinator9889 on 06/04/2018.
+ */
+public class BackupManager implements IBackup {
+ private IDriveUploader mUploader;
+ private IDriveDownloader mDownloader;
+
+ /**
+ * Public constructor for managing backups
+ *
+ * @param backupContext Context
when instantiating this class
+ * @param sourceActivity Activity
when instantiating this class
+ * @see Activity
+ * @see Context
+ * @see DriveUploader
+ * @see DriveDownloader
+ */
+ public BackupManager(@NonNull Context backupContext, @NonNull Activity sourceActivity) {
+ this.mUploader = new DriveUploader(backupContext, sourceActivity);
+ this.mDownloader = new DriveDownloader(backupContext, sourceActivity);
+ }
+
+ /**
+ * Does the backup by using
+ * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class
+ *
+ * @see javinator9889.securepass.backup.drive.IDriveUploader
+ */
+ @Override
+ public void doBackup() {
+ this.mUploader.uploadDatabase();
+ }
+
+ /**
+ * Restores the backup by using
+ * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
+ *
+ * @see javinator9889.securepass.backup.drive.IDriveDownloader
+ */
+ @Override
+ public void restoreBackup() {
+
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/IBackup.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/IBackup.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/backup/IBackup.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/IBackup.java
index 10464a6..e6c8981 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/IBackup.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/IBackup.java
@@ -1,23 +1,23 @@
-package javinator9889.securepass.backup;
-
-/**
- * Interface for accessing {@link BackupManager BackupManager class}
- * Created by Javinator9889 on 20/09/2018.
- */
-public interface IBackup {
- /**
- * Does the backup by using
- * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class
- *
- * @see javinator9889.securepass.backup.drive.IDriveUploader
- */
- void doBackup();
-
- /**
- * Restores the backup by using
- * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
- *
- * @see javinator9889.securepass.backup.drive.IDriveDownloader
- */
- void restoreBackup();
-}
+package javinator9889.securepass.backup;
+
+/**
+ * Interface for accessing {@link BackupManager BackupManager class}
+ * Created by Javinator9889 on 20/09/2018.
+ */
+public interface IBackup {
+ /**
+ * Does the backup by using
+ * {@link javinator9889.securepass.backup.drive.DriveUploader DriveUploader} class
+ *
+ * @see javinator9889.securepass.backup.drive.IDriveUploader
+ */
+ void doBackup();
+
+ /**
+ * Restores the backup by using
+ * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
+ *
+ * @see javinator9889.securepass.backup.drive.IDriveDownloader
+ */
+ void restoreBackup();
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java
similarity index 97%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java
index 88c8664..58bf6bb 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveDownloader.java
@@ -1,196 +1,196 @@
-package javinator9889.securepass.backup.drive;
-
-import android.app.Activity;
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.google.android.gms.drive.DriveContents;
-import com.google.android.gms.drive.DriveFile;
-import com.google.android.gms.drive.DriveResourceClient;
-import com.google.android.gms.drive.Metadata;
-import com.google.android.gms.drive.events.OpenFileCallback;
-import com.google.android.gms.drive.widget.DataBufferAdapter;
-import com.google.android.gms.tasks.Task;
-import com.google.common.hash.Hashing;
-import com.google.common.io.ByteStreams;
-import com.google.common.io.Files;
-
-import net.sqlcipher.database.SQLiteDatabase;
-import net.sqlcipher.database.SQLiteException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.R;
-import javinator9889.securepass.backup.drive.base.GoogleDriveBase;
-import javinator9889.securepass.io.IOManager;
-import javinator9889.securepass.objects.ByteArrayKeeper;
-import javinator9889.securepass.util.cipher.FileCipher;
-import javinator9889.securepass.util.cipher.ICipher;
-
-/**
- * Class for downloading files into the device
- * Created by Javinator9889 on 03/09/2018.
- *
- * @see GoogleDriveBase
- * @see IDriveDownloader
- */
-public class DriveDownloader extends GoogleDriveBase implements IDriveDownloader {
- private static final String TAG = "DriveDownloader";
- private MaterialDialog mProgressBar;
-
- /**
- * Public constructor for starting the download activity
- *
- * @param driveContext Context
when instantiating this class
- * @param mainActivity Activity
when instantiating this class
- * @see Context
- * @see Activity
- * @see GoogleDriveBase
- * @see MaterialDialog
- */
- public DriveDownloader(@NonNull Context driveContext, @NonNull Activity mainActivity) {
- super(driveContext, mainActivity);
- super.signIn();
- mProgressBar = new MaterialDialog.Builder(driveContext)
- .title(R.string.retrieving_data)
- .content(R.string.wait)
- .cancelable(false)
- .progress(false, 100)
- .build();
- }
-
- /**
- * Restores the data and saves it into a ResultsAdapter
- *
- * @see DataBufferAdapter
- * @see DriveFile
- * @see Task
- */
- @Override
- public void restoreData() {
- IOManager ioManager = IOManager.newInstance(getDriveContext());
- final ByteArrayKeeper ivVector = new ByteArrayKeeper();
- if (!ioManager.isAnyIVVectorStored()) {
- DataBufferAdapter vectorData = new ResultsAdapter(getDriveContext());
- getIVVector(vectorData);
- DriveFile vectorFile = null;
- for (int i = 0; i < vectorData.getCount(); ++i)
- vectorFile = vectorData.getItem(i).getDriveId().asDriveFile();
- Task ivFileTask = getDriveResourceClient()
- .openFile(vectorFile, DriveFile.MODE_READ_ONLY);
- ivFileTask.continueWith(task -> {
- DriveContents contents = task.getResult();
- try (InputStream stream = contents.getInputStream()) {
- ivVector.storeArray(ByteStreams.toByteArray(stream));
- return getDriveResourceClient().discardContents(contents);
- }
- });
- try {
- ioManager.saveIVVector(ivVector.getArray());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- DataBufferAdapter databaseBackup = new ResultsAdapter(getDriveContext());
- super.queryFiles(databaseBackup);
- DriveFile databaseFile = null;
- for (int i = 0; i < databaseBackup.getCount(); ++i)
- databaseFile = databaseBackup.getItem(i).getDriveId().asDriveFile();
- retrieveContents(databaseFile);
- }
-
- /**
- * Retrieves contents by using supper methods for querying and saving files
- *
- * @param contents a DriveFile
which has the databaseFile
- * @see #restoreData()
- */
- private void retrieveContents(@NonNull DriveFile contents) {
- mProgressBar.show();
- final DriveResourceClient resourceClient = super.getDriveResourceClient();
- final Context driveContext = super.getDriveContext();
- resourceClient.openFile(contents, DriveFile.MODE_READ_ONLY,
- new OpenFileCallback() {
- @Override
- public void onProgress(long bytesDownloaded, long bytesExpected) {
- int progress = (int) ((bytesDownloaded * 100) / bytesExpected);
- Log.d(TAG, String.format("Download progress: %d percent", progress));
- mProgressBar.setProgress(progress);
- }
-
- @Override
- public void onContents(@NonNull DriveContents driveContents) {
- mProgressBar.setProgress(100);
- try {
- try (InputStream obtainedFile = driveContents.getInputStream()) {
- ICipher cipher = new FileCipher(driveContext);
- IOManager io = IOManager.newInstance(driveContext);
- File destination = new File(io.downloadedDatabaseBackupPath());
- cipher.decryptFile(obtainedFile, destination);
- mProgressBar.dismiss();
- completeDownload();
- }
- } catch (Exception e) {
- Log.e(TAG, "Exception while copying/retrieving database", e);
- }
- }
-
- @Override
- public void onError(@NonNull Exception e) {
- Log.e(TAG, "Exception while downloading/retrieving contents", e);
- }
- });
- }
-
- /**
- * As the database is encrypted, we must check if the user knows the password which used for
- * doing the encryption
- *
- * @see SQLiteDatabase
- * @see IOManager
- */
- private void completeDownload() {
- final Context driveContext = super.getDriveContext();
- SQLiteDatabase.loadLibs(driveContext);
- IOManager io = IOManager.newInstance(driveContext);
- String databaseDownloadedBackupPath = io.downloadedDatabaseBackupPath();
- final StringBuilder passwordBuilder = new StringBuilder();
- MaterialDialog passwordInputDialog = new MaterialDialog.Builder(driveContext)
- .title(R.string.put_pass)
- .content(R.string.pass_need)
- .inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD)
- .input(null, null, false,
- ((dialog, input) -> passwordBuilder.append(input)))
- .onAny(((dialog, which) -> {
- final String password = Hashing.sha256()
- .hashString(passwordBuilder.toString(), StandardCharsets.UTF_8)
- .toString();
- try {
- SQLiteDatabase openedDatabase = SQLiteDatabase
- .openDatabase(databaseDownloadedBackupPath, password, null,
- SQLiteDatabase.OPEN_READONLY);
- openedDatabase.close();
- File databaseBackup = new File(databaseDownloadedBackupPath);
- File databasePath = io.getDatabasePath();
- try {
- Files.move(databaseBackup, databasePath);
- showMessage("Backup restore completed");
- } catch (IOException e) {
- showMessage("Error while recovering your backup");
- }
- } catch (SQLiteException e) {
- showMessage("Password not correct");
- completeDownload();
- }
- }))
- .cancelable(false)
- .build();
- passwordInputDialog.show();
- }
-}
+package javinator9889.securepass.backup.drive;
+
+import android.app.Activity;
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+import com.google.android.gms.drive.DriveContents;
+import com.google.android.gms.drive.DriveFile;
+import com.google.android.gms.drive.DriveResourceClient;
+import com.google.android.gms.drive.Metadata;
+import com.google.android.gms.drive.events.OpenFileCallback;
+import com.google.android.gms.drive.widget.DataBufferAdapter;
+import com.google.android.gms.tasks.Task;
+import com.google.common.hash.Hashing;
+import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
+
+import net.sqlcipher.database.SQLiteDatabase;
+import net.sqlcipher.database.SQLiteException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.R;
+import javinator9889.securepass.backup.drive.base.GoogleDriveBase;
+import javinator9889.securepass.io.IOManager;
+import javinator9889.securepass.objects.ByteArrayKeeper;
+import javinator9889.securepass.util.cipher.FileCipher;
+import javinator9889.securepass.util.cipher.ICipher;
+
+/**
+ * Class for downloading files into the device
+ * Created by Javinator9889 on 03/09/2018.
+ *
+ * @see GoogleDriveBase
+ * @see IDriveDownloader
+ */
+public class DriveDownloader extends GoogleDriveBase implements IDriveDownloader {
+ private static final String TAG = "DriveDownloader";
+ private MaterialDialog mProgressBar;
+
+ /**
+ * Public constructor for starting the download activity
+ *
+ * @param driveContext Context
when instantiating this class
+ * @param mainActivity Activity
when instantiating this class
+ * @see Context
+ * @see Activity
+ * @see GoogleDriveBase
+ * @see MaterialDialog
+ */
+ public DriveDownloader(@NonNull Context driveContext, @NonNull Activity mainActivity) {
+ super(driveContext, mainActivity);
+ super.signIn();
+ mProgressBar = new MaterialDialog.Builder(driveContext)
+ .title(R.string.retrieving_data)
+ .content(R.string.wait)
+ .cancelable(false)
+ .progress(false, 100)
+ .build();
+ }
+
+ /**
+ * Restores the data and saves it into a ResultsAdapter
+ *
+ * @see DataBufferAdapter
+ * @see DriveFile
+ * @see Task
+ */
+ @Override
+ public void restoreData() {
+ IOManager ioManager = IOManager.newInstance(getDriveContext());
+ final ByteArrayKeeper ivVector = new ByteArrayKeeper();
+ if (!ioManager.isAnyIVVectorStored()) {
+ DataBufferAdapter vectorData = new ResultsAdapter(getDriveContext());
+ getIVVector(vectorData);
+ DriveFile vectorFile = null;
+ for (int i = 0; i < vectorData.getCount(); ++i)
+ vectorFile = vectorData.getItem(i).getDriveId().asDriveFile();
+ Task ivFileTask = getDriveResourceClient()
+ .openFile(vectorFile, DriveFile.MODE_READ_ONLY);
+ ivFileTask.continueWith(task -> {
+ DriveContents contents = task.getResult();
+ try (InputStream stream = contents.getInputStream()) {
+ ivVector.storeArray(ByteStreams.toByteArray(stream));
+ return getDriveResourceClient().discardContents(contents);
+ }
+ });
+ try {
+ ioManager.saveIVVector(ivVector.getArray());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ DataBufferAdapter databaseBackup = new ResultsAdapter(getDriveContext());
+ super.queryFiles(databaseBackup);
+ DriveFile databaseFile = null;
+ for (int i = 0; i < databaseBackup.getCount(); ++i)
+ databaseFile = databaseBackup.getItem(i).getDriveId().asDriveFile();
+ retrieveContents(databaseFile);
+ }
+
+ /**
+ * Retrieves contents by using supper methods for querying and saving files
+ *
+ * @param contents a DriveFile
which has the databaseFile
+ * @see #restoreData()
+ */
+ private void retrieveContents(@NonNull DriveFile contents) {
+ mProgressBar.show();
+ final DriveResourceClient resourceClient = super.getDriveResourceClient();
+ final Context driveContext = super.getDriveContext();
+ resourceClient.openFile(contents, DriveFile.MODE_READ_ONLY,
+ new OpenFileCallback() {
+ @Override
+ public void onProgress(long bytesDownloaded, long bytesExpected) {
+ int progress = (int) ((bytesDownloaded * 100) / bytesExpected);
+ Log.d(TAG, String.format("Download progress: %d percent", progress));
+ mProgressBar.setProgress(progress);
+ }
+
+ @Override
+ public void onContents(@NonNull DriveContents driveContents) {
+ mProgressBar.setProgress(100);
+ try {
+ try (InputStream obtainedFile = driveContents.getInputStream()) {
+ ICipher cipher = new FileCipher(driveContext);
+ IOManager io = IOManager.newInstance(driveContext);
+ File destination = new File(io.downloadedDatabaseBackupPath());
+ cipher.decryptFile(obtainedFile, destination);
+ mProgressBar.dismiss();
+ completeDownload();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception while copying/retrieving database", e);
+ }
+ }
+
+ @Override
+ public void onError(@NonNull Exception e) {
+ Log.e(TAG, "Exception while downloading/retrieving contents", e);
+ }
+ });
+ }
+
+ /**
+ * As the database is encrypted, we must check if the user knows the password which used for
+ * doing the encryption
+ *
+ * @see SQLiteDatabase
+ * @see IOManager
+ */
+ private void completeDownload() {
+ final Context driveContext = super.getDriveContext();
+ SQLiteDatabase.loadLibs(driveContext);
+ IOManager io = IOManager.newInstance(driveContext);
+ String databaseDownloadedBackupPath = io.downloadedDatabaseBackupPath();
+ final StringBuilder passwordBuilder = new StringBuilder();
+ MaterialDialog passwordInputDialog = new MaterialDialog.Builder(driveContext)
+ .title(R.string.put_pass)
+ .content(R.string.pass_need)
+ .inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD)
+ .input(null, null, false,
+ ((dialog, input) -> passwordBuilder.append(input)))
+ .onAny(((dialog, which) -> {
+ final String password = Hashing.sha256()
+ .hashString(passwordBuilder.toString(), StandardCharsets.UTF_8)
+ .toString();
+ try {
+ SQLiteDatabase openedDatabase = SQLiteDatabase
+ .openDatabase(databaseDownloadedBackupPath, password, null,
+ SQLiteDatabase.OPEN_READONLY);
+ openedDatabase.close();
+ File databaseBackup = new File(databaseDownloadedBackupPath);
+ File databasePath = io.getDatabasePath();
+ try {
+ Files.move(databaseBackup, databasePath);
+ showMessage("Backup restore completed");
+ } catch (IOException e) {
+ showMessage("Error while recovering your backup");
+ }
+ } catch (SQLiteException e) {
+ showMessage("Password not correct");
+ completeDownload();
+ }
+ }))
+ .cancelable(false)
+ .build();
+ passwordInputDialog.show();
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java
similarity index 97%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java
index 87fac4f..c1886fa 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/DriveUploader.java
@@ -1,224 +1,224 @@
-package javinator9889.securepass.backup.drive;
-
-import android.app.Activity;
-import android.content.Context;
-import android.util.Log;
-
-import com.google.android.gms.drive.DriveContents;
-import com.google.android.gms.drive.DriveFolder;
-import com.google.android.gms.drive.DriveResource;
-import com.google.android.gms.drive.DriveResourceClient;
-import com.google.android.gms.drive.Metadata;
-import com.google.android.gms.drive.MetadataChangeSet;
-import com.google.android.gms.drive.widget.DataBufferAdapter;
-import com.google.android.gms.tasks.Task;
-import com.google.android.gms.tasks.Tasks;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.backup.drive.base.GoogleDriveBase;
-import javinator9889.securepass.io.IOManager;
-import javinator9889.securepass.objects.GeneralObjectContainer;
-import javinator9889.securepass.objects.ObjectContainer;
-import javinator9889.securepass.util.cipher.FileCipher;
-import javinator9889.securepass.util.cipher.ICipher;
-import javinator9889.securepass.util.values.Constants;
-
-/**
- * Class for uploading files to app folder at Google Drive
- *
- * @see GoogleDriveBase
- * @see IDriveUploader
- * Created by Javinator9889 on 24/08/2018.
- */
-public class DriveUploader extends GoogleDriveBase implements IDriveUploader {
- private static final String TAG = "DriveUploader";
- private ICipher mFileCipher;
- private IOManager mIOManager;
-
- /**
- * Public constructor for starting the upload activity
- *
- * @param driveContext Context
when instantiating this class
- * @param mainActivity Activity
when instantiating this class
- * @see Activity
- * @see Context
- * @see GoogleDriveBase
- * @see FileCipher
- */
- public DriveUploader(@NonNull Context driveContext, @NonNull Activity mainActivity) {
- super(driveContext, mainActivity);
- super.signIn();
- this.mFileCipher = new FileCipher(driveContext);
- this.mIOManager = IOManager.newInstance(driveContext);
- }
-
- /**
- * Creates a file inside the app folder at Google Drive
- *
- * First, it ciphers the object (database) to upload.
- * Then, it tries to upload that such file (stored temporally at cache dir) by
- * setting the {@link Constants.SQL} DB_FILENAME
and the
- * {@link Constants.DRIVE} MIME_TYPE
- *
- * Also it uploads the necessary IV Vector for encrypting/decrypting the file
- *
- *
- * @see DriveResourceClient
- * @see FileCipher#encryptFile(File, File)
- * @see Tasks
- * @see Files#copy(File, OutputStream)
- * @see MetadataChangeSet
- */
- private void createFileInAppFolder() {
- final DriveResourceClient resourceClient = super.getDriveResourceClient();
- final Context driveContext = super.getDriveContext();
- final Activity driveActivity = super.getMainActivity();
- final Task appFolderTask = resourceClient.getAppFolder();
- final Task driveContentTask = resourceClient.createContents();
- final GeneralObjectContainer fileContainer = new ObjectContainer<>(1);
- try {
- fileContainer.storeObject(new File(driveContext.getCacheDir().getAbsolutePath() +
- "/SecurePass.crypt.db"));
- mFileCipher.encryptFile(mIOManager.getDatabasePath(),
- fileContainer.getLatestStoredObject());
- } catch (NoSuchPaddingException | NoSuchAlgorithmException |
- InvalidAlgorithmParameterException | InvalidKeyException | BadPaddingException |
- IllegalBlockSizeException | IOException e) {
- Log.e(TAG, "Error while encrypting file - working at insecure mode | More info: "
- + e.getMessage());
- fileContainer.storeObject(mIOManager.getDatabasePath());
- } finally {
- Tasks.whenAll(appFolderTask, driveContentTask)
- .continueWith(task -> {
- DriveFolder appFolder = appFolderTask.getResult();
- DriveContents folderContents = driveContentTask.getResult();
- try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) {
- Files.copy(fileContainer.getLatestStoredObject(), streamToGoogleDrive);
- }
- MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
- .setTitle(Constants.SQL.DB_FILENAME)
- .setMimeType(Constants.DRIVE.MIME_TYPE)
- .setPinned(true)
- .build();
- return resourceClient.createFile(appFolder, changeSet, folderContents);
- })
- .addOnSuccessListener(driveActivity, driveFileTask -> {
- int uploadIVVectorStatus = uploadIVVector();
- if (uploadIVVectorStatus == 0)
- showMessage("DB file uploaded");
- else
- showMessage("Error uploading file");
- })
- .addOnFailureListener(driveActivity, e -> {
- Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e);
- showMessage("Error while uploading");
- });
- finalizeUpload(fileContainer.getLatestStoredObject());
- }
- }
-
- /**
- * After uploading the database, it must destroy the cached version
- *
- * @param sourceFile path for the file to be deleted if possible
- * @see File#equals(Object)
- * @see File#delete()
- */
- private void finalizeUpload(@NonNull File sourceFile) {
- if (!sourceFile.equals(mIOManager.getDatabasePath())) {
- sourceFile.delete();
- }
- }
-
- /**
- * Uploads the IV Vector to the app folder at Google Drive. It must be uploaded once
- *
- * @return int value which represents the status of the stored object: '0' if everything has
- * gone well, else '-1'
- * @see Tasks
- * @see ObjectContainer#getLatestStoredObject()
- */
- private int uploadIVVector() {
- final DriveResourceClient resourceClient = super.getDriveResourceClient();
- final Activity driveActivity = super.getMainActivity();
- final Task appFolderTask = resourceClient.getAppFolder();
- final Task driveContentTask = resourceClient.createContents();
- final GeneralObjectContainer status = new ObjectContainer<>(1);
- Tasks.whenAll(appFolderTask, driveContentTask)
- .continueWith(task -> {
- DriveFolder appFolder = appFolderTask.getResult();
- DriveContents folderContents = driveContentTask.getResult();
- try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) {
- Files.copy(mIOManager.getIVVector(), streamToGoogleDrive);
- }
- MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
- .setTitle(Constants.DRIVE.IV_FILE)
- .setMimeType(Constants.DRIVE.IV_MIME_TYPE)
- .build();
- return resourceClient.createFile(appFolder, changeSet, folderContents);
- })
- .addOnSuccessListener(driveActivity, driveFileTask -> status.storeObject(0))
- .addOnFailureListener(driveActivity, e -> {
- Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e);
- status.storeObject(-1);
- });
- return status.getLatestStoredObject();
- }
-
- /**
- * Deletes old files if found at the Google Drive app folder, in order to only store and save
- * the latest one
- *
- * @param resultsAdapter container with all the found objects that can be deleted
- */
- private void deleteOldFiles(DataBufferAdapter resultsAdapter) {
- int resultsFound = resultsAdapter.getCount();
- for (int i = 0; i < resultsFound; ++i) {
- DriveResource fileToDelete = resultsAdapter.getItem(i).getDriveId().asDriveResource();
- getDriveResourceClient().delete(fileToDelete);
- }
- }
-
- /**
- * General public method which invokes in order the following ones:
- *
- * -
- * {@link #isAbleToSignIn()}
- *
- * -
- * {@link #queryFiles(DataBufferAdapter)}
- *
- * -
- * {@link #createFileInAppFolder()}
- *
- * -
- * {@link #deleteOldFiles(DataBufferAdapter)}
- *
- *
- *
- * @see DataBufferAdapter
- * @see ResultsAdapter
- * @see GoogleDriveBase
- */
- @Override
- public void uploadDatabase() {
- DataBufferAdapter resultsAdapter = new ResultsAdapter(getDriveContext());
- if (super.isAbleToSignIn()) {
- queryFiles(resultsAdapter);
- createFileInAppFolder();
- deleteOldFiles(resultsAdapter);
- }
- }
-}
+package javinator9889.securepass.backup.drive;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.Log;
+
+import com.google.android.gms.drive.DriveContents;
+import com.google.android.gms.drive.DriveFolder;
+import com.google.android.gms.drive.DriveResource;
+import com.google.android.gms.drive.DriveResourceClient;
+import com.google.android.gms.drive.Metadata;
+import com.google.android.gms.drive.MetadataChangeSet;
+import com.google.android.gms.drive.widget.DataBufferAdapter;
+import com.google.android.gms.tasks.Task;
+import com.google.android.gms.tasks.Tasks;
+import com.google.common.io.Files;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.backup.drive.base.GoogleDriveBase;
+import javinator9889.securepass.io.IOManager;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.cipher.FileCipher;
+import javinator9889.securepass.util.cipher.ICipher;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Class for uploading files to app folder at Google Drive
+ *
+ * @see GoogleDriveBase
+ * @see IDriveUploader
+ * Created by Javinator9889 on 24/08/2018.
+ */
+public class DriveUploader extends GoogleDriveBase implements IDriveUploader {
+ private static final String TAG = "DriveUploader";
+ private ICipher mFileCipher;
+ private IOManager mIOManager;
+
+ /**
+ * Public constructor for starting the upload activity
+ *
+ * @param driveContext Context
when instantiating this class
+ * @param mainActivity Activity
when instantiating this class
+ * @see Activity
+ * @see Context
+ * @see GoogleDriveBase
+ * @see FileCipher
+ */
+ public DriveUploader(@NonNull Context driveContext, @NonNull Activity mainActivity) {
+ super(driveContext, mainActivity);
+ super.signIn();
+ this.mFileCipher = new FileCipher(driveContext);
+ this.mIOManager = IOManager.newInstance(driveContext);
+ }
+
+ /**
+ * Creates a file inside the app folder at Google Drive
+ *
+ * First, it ciphers the object (database) to upload.
+ * Then, it tries to upload that such file (stored temporally at cache dir) by
+ * setting the {@link Constants.SQL} DB_FILENAME
and the
+ * {@link Constants.DRIVE} MIME_TYPE
+ *
+ * Also it uploads the necessary IV Vector for encrypting/decrypting the file
+ *
+ *
+ * @see DriveResourceClient
+ * @see FileCipher#encryptFile(File, File)
+ * @see Tasks
+ * @see Files#copy(File, OutputStream)
+ * @see MetadataChangeSet
+ */
+ private void createFileInAppFolder() {
+ final DriveResourceClient resourceClient = super.getDriveResourceClient();
+ final Context driveContext = super.getDriveContext();
+ final Activity driveActivity = super.getMainActivity();
+ final Task appFolderTask = resourceClient.getAppFolder();
+ final Task driveContentTask = resourceClient.createContents();
+ final GeneralObjectContainer fileContainer = new ObjectContainer<>(1);
+ try {
+ fileContainer.storeObject(new File(driveContext.getCacheDir().getAbsolutePath() +
+ "/SecurePass.crypt.db"));
+ mFileCipher.encryptFile(mIOManager.getDatabasePath(),
+ fileContainer.getLatestStoredObject());
+ } catch (NoSuchPaddingException | NoSuchAlgorithmException |
+ InvalidAlgorithmParameterException | InvalidKeyException | BadPaddingException |
+ IllegalBlockSizeException | IOException e) {
+ Log.e(TAG, "Error while encrypting file - working at insecure mode | More info: "
+ + e.getMessage());
+ fileContainer.storeObject(mIOManager.getDatabasePath());
+ } finally {
+ Tasks.whenAll(appFolderTask, driveContentTask)
+ .continueWith(task -> {
+ DriveFolder appFolder = appFolderTask.getResult();
+ DriveContents folderContents = driveContentTask.getResult();
+ try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) {
+ Files.copy(fileContainer.getLatestStoredObject(), streamToGoogleDrive);
+ }
+ MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
+ .setTitle(Constants.SQL.DB_FILENAME)
+ .setMimeType(Constants.DRIVE.MIME_TYPE)
+ .setPinned(true)
+ .build();
+ return resourceClient.createFile(appFolder, changeSet, folderContents);
+ })
+ .addOnSuccessListener(driveActivity, driveFileTask -> {
+ int uploadIVVectorStatus = uploadIVVector();
+ if (uploadIVVectorStatus == 0)
+ showMessage("DB file uploaded");
+ else
+ showMessage("Error uploading file");
+ })
+ .addOnFailureListener(driveActivity, e -> {
+ Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e);
+ showMessage("Error while uploading");
+ });
+ finalizeUpload(fileContainer.getLatestStoredObject());
+ }
+ }
+
+ /**
+ * After uploading the database, it must destroy the cached version
+ *
+ * @param sourceFile path for the file to be deleted if possible
+ * @see File#equals(Object)
+ * @see File#delete()
+ */
+ private void finalizeUpload(@NonNull File sourceFile) {
+ if (!sourceFile.equals(mIOManager.getDatabasePath())) {
+ sourceFile.delete();
+ }
+ }
+
+ /**
+ * Uploads the IV Vector to the app folder at Google Drive. It must be uploaded once
+ *
+ * @return int value which represents the status of the stored object: '0' if everything has
+ * gone well, else '-1'
+ * @see Tasks
+ * @see ObjectContainer#getLatestStoredObject()
+ */
+ private int uploadIVVector() {
+ final DriveResourceClient resourceClient = super.getDriveResourceClient();
+ final Activity driveActivity = super.getMainActivity();
+ final Task appFolderTask = resourceClient.getAppFolder();
+ final Task driveContentTask = resourceClient.createContents();
+ final GeneralObjectContainer status = new ObjectContainer<>(1);
+ Tasks.whenAll(appFolderTask, driveContentTask)
+ .continueWith(task -> {
+ DriveFolder appFolder = appFolderTask.getResult();
+ DriveContents folderContents = driveContentTask.getResult();
+ try (OutputStream streamToGoogleDrive = folderContents.getOutputStream()) {
+ Files.copy(mIOManager.getIVVector(), streamToGoogleDrive);
+ }
+ MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
+ .setTitle(Constants.DRIVE.IV_FILE)
+ .setMimeType(Constants.DRIVE.IV_MIME_TYPE)
+ .build();
+ return resourceClient.createFile(appFolder, changeSet, folderContents);
+ })
+ .addOnSuccessListener(driveActivity, driveFileTask -> status.storeObject(0))
+ .addOnFailureListener(driveActivity, e -> {
+ Log.e(TAG, Constants.DRIVE.GOOGLE_DRIVE_FILE_NOT_CREATED, e);
+ status.storeObject(-1);
+ });
+ return status.getLatestStoredObject();
+ }
+
+ /**
+ * Deletes old files if found at the Google Drive app folder, in order to only store and save
+ * the latest one
+ *
+ * @param resultsAdapter container with all the found objects that can be deleted
+ */
+ private void deleteOldFiles(DataBufferAdapter resultsAdapter) {
+ int resultsFound = resultsAdapter.getCount();
+ for (int i = 0; i < resultsFound; ++i) {
+ DriveResource fileToDelete = resultsAdapter.getItem(i).getDriveId().asDriveResource();
+ getDriveResourceClient().delete(fileToDelete);
+ }
+ }
+
+ /**
+ * General public method which invokes in order the following ones:
+ *
+ * -
+ * {@link #isAbleToSignIn()}
+ *
+ * -
+ * {@link #queryFiles(DataBufferAdapter)}
+ *
+ * -
+ * {@link #createFileInAppFolder()}
+ *
+ * -
+ * {@link #deleteOldFiles(DataBufferAdapter)}
+ *
+ *
+ *
+ * @see DataBufferAdapter
+ * @see ResultsAdapter
+ * @see GoogleDriveBase
+ */
+ @Override
+ public void uploadDatabase() {
+ DataBufferAdapter resultsAdapter = new ResultsAdapter(getDriveContext());
+ if (super.isAbleToSignIn()) {
+ queryFiles(resultsAdapter);
+ createFileInAppFolder();
+ deleteOldFiles(resultsAdapter);
+ }
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java
index da93d29..6b8428d 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveDownloader.java
@@ -1,20 +1,20 @@
-package javinator9889.securepass.backup.drive;
-
-import com.google.android.gms.drive.DriveFile;
-import com.google.android.gms.drive.widget.DataBufferAdapter;
-import com.google.android.gms.tasks.Task;
-
-/**
- * Interface for accessing {@link DriveDownloader}
- * Created by Javinator9889 on 03/09/2018.
- */
-public interface IDriveDownloader {
- /**
- * Restores the data and saves it into a ResultsAdapter
- *
- * @see DataBufferAdapter
- * @see DriveFile
- * @see Task
- */
- void restoreData();
-}
+package javinator9889.securepass.backup.drive;
+
+import com.google.android.gms.drive.DriveFile;
+import com.google.android.gms.drive.widget.DataBufferAdapter;
+import com.google.android.gms.tasks.Task;
+
+/**
+ * Interface for accessing {@link DriveDownloader}
+ * Created by Javinator9889 on 03/09/2018.
+ */
+public interface IDriveDownloader {
+ /**
+ * Restores the data and saves it into a ResultsAdapter
+ *
+ * @see DataBufferAdapter
+ * @see DriveFile
+ * @see Task
+ */
+ void restoreData();
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java
index 8b54d20..e23d798 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/IDriveUploader.java
@@ -1,34 +1,34 @@
-package javinator9889.securepass.backup.drive;
-
-import com.google.android.gms.drive.widget.DataBufferAdapter;
-
-import javinator9889.securepass.backup.drive.base.GoogleDriveBase;
-
-/**
- * Interface for accessing {@link DriveUploader}
- * Created by Javinator9889 on 24/08/2018.
- */
-public interface IDriveUploader {
- /**
- * General public method which invokes in order the following ones:
- *
- * -
- * {@link DriveUploader#isAbleToSignIn()} ()}
- *
- * -
- * {@link DriveUploader#queryFiles(DataBufferAdapter)}
- *
- * -
- * {@link DriveUploader#createFileInAppFolder()}
- *
- * -
- * {@link DriveUploader#deleteOldFiles(DataBufferAdapter)}
- *
- *
- *
- * @see DataBufferAdapter
- * @see ResultsAdapter
- * @see GoogleDriveBase
- */
- void uploadDatabase();
-}
+package javinator9889.securepass.backup.drive;
+
+import com.google.android.gms.drive.widget.DataBufferAdapter;
+
+import javinator9889.securepass.backup.drive.base.GoogleDriveBase;
+
+/**
+ * Interface for accessing {@link DriveUploader}
+ * Created by Javinator9889 on 24/08/2018.
+ */
+public interface IDriveUploader {
+ /**
+ * General public method which invokes in order the following ones:
+ *
+ * -
+ * {@link DriveUploader#isAbleToSignIn()} ()}
+ *
+ * -
+ * {@link DriveUploader#queryFiles(DataBufferAdapter)}
+ *
+ * -
+ * {@link DriveUploader#createFileInAppFolder()}
+ *
+ * -
+ * {@link DriveUploader#deleteOldFiles(DataBufferAdapter)}
+ *
+ *
+ *
+ * @see DataBufferAdapter
+ * @see ResultsAdapter
+ * @see GoogleDriveBase
+ */
+ void uploadDatabase();
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java
index 0edb9ec..dc5cac1 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/ResultsAdapter.java
@@ -1,28 +1,28 @@
-package javinator9889.securepass.backup.drive;
-
-import android.content.Context;
-
-import com.google.android.gms.drive.Metadata;
-import com.google.android.gms.drive.widget.DataBufferAdapter;
-
-import androidx.annotation.NonNull;
-
-/**
- * Store and save recovered documents from Google Drive
- *
- * @see DataBufferAdapter
- * @see Metadata
- * Created by Javinator9889 on 07/04/2018.
- */
-public class ResultsAdapter extends DataBufferAdapter {
- /**
- * Required public constructor that invokes
- * {@link DataBufferAdapter#DataBufferAdapter(Context, int) super method} super ones with a
- * {@link android.R.layout#simple_list_item_1 simple list item} by default
- *
- * @param context Context
when instantiating this class
- */
- public ResultsAdapter(@NonNull Context context) {
- super(context, android.R.layout.simple_list_item_1);
- }
-}
+package javinator9889.securepass.backup.drive;
+
+import android.content.Context;
+
+import com.google.android.gms.drive.Metadata;
+import com.google.android.gms.drive.widget.DataBufferAdapter;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Store and save recovered documents from Google Drive
+ *
+ * @see DataBufferAdapter
+ * @see Metadata
+ * Created by Javinator9889 on 07/04/2018.
+ */
+public class ResultsAdapter extends DataBufferAdapter {
+ /**
+ * Required public constructor that invokes
+ * {@link DataBufferAdapter#DataBufferAdapter(Context, int) super method} super ones with a
+ * {@link android.R.layout#simple_list_item_1 simple list item} by default
+ *
+ * @param context Context
when instantiating this class
+ */
+ public ResultsAdapter(@NonNull Context context) {
+ super(context, android.R.layout.simple_list_item_1);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java
similarity index 97%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java
index d3b1def..e67bc4f 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/GoogleDriveBase.java
@@ -1,246 +1,246 @@
-package javinator9889.securepass.backup.drive.base;
-
-import android.app.Activity;
-import android.content.Context;
-import android.widget.Toast;
-
-import com.google.android.gms.auth.api.signin.GoogleSignIn;
-import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
-import com.google.android.gms.drive.Drive;
-import com.google.android.gms.drive.DriveFolder;
-import com.google.android.gms.drive.DriveResourceClient;
-import com.google.android.gms.drive.Metadata;
-import com.google.android.gms.drive.MetadataBuffer;
-import com.google.android.gms.drive.query.Filters;
-import com.google.android.gms.drive.query.Query;
-import com.google.android.gms.drive.query.SearchableField;
-import com.google.android.gms.drive.query.SortOrder;
-import com.google.android.gms.drive.query.SortableField;
-import com.google.android.gms.drive.widget.DataBufferAdapter;
-import com.google.android.gms.tasks.Task;
-
-import java.security.Key;
-import java.security.spec.AlgorithmParameterSpec;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.StringRes;
-import javinator9889.securepass.R;
-import javinator9889.securepass.backup.drive.ResultsAdapter;
-import javinator9889.securepass.util.values.Constants;
-import javinator9889.securepass.util.values.Constants.DRIVE;
-
-/**
- * Created by Javinator9889 on 24/04/2018.
- * Base class for managing Google Drive connections
- */
-public class GoogleDriveBase implements IDriveBase {
- private static final String TAG = "drive-base";
- private Context mDriveContext;
- private Activity mMainActivity;
- private DriveResourceClient mDriveResourceClient;
- private DataBufferAdapter mResultsAdapter;
- private SignIn mSignInClient;
-
- /**
- * Public constructor for base class
- *
- * @param driveContext Context
when initializing this class
- * @param mainActivity Activity
when initializing this class
- * @see Context
- * @see Activity
- */
- public GoogleDriveBase(@NonNull Context driveContext, @NonNull Activity mainActivity) {
- this.mDriveContext = driveContext;
- this.mMainActivity = mainActivity;
- mSignInClient = SignIn.getInstance(mainActivity, driveContext);
- mResultsAdapter = new ResultsAdapter(driveContext);
- }
-
- /**
- * Obtains Context
- *
- * @return Context
object
- * @see Context
- */
- public Context getDriveContext() {
- return mDriveContext;
- }
-
- /**
- * Obtains Activity
- *
- * @return Activity
object
- * @see Activity
- */
- public Activity getMainActivity() {
- return mMainActivity;
- }
-
- /**
- * Obtains the ResultsAdapter
- *
- * @return DataBufferAdapter of Metadata
object
- * @see DataBufferAdapter
- * @see Metadata
- */
- public DataBufferAdapter getResultsAdapter() {
- return mResultsAdapter;
- }
-
- /**
- * Obtains the DriveResourceClient
- *
- * @return DriveResourceClient
object
- * @see DriveResourceClient
- */
- public DriveResourceClient getDriveResourceClient() {
- return mDriveResourceClient;
- }
-
- /**
- * Obtains the SignInClient
- *
- * @return SignIn
object
- * @see SignIn
- */
- public SignIn getSignInClient() {
- return mSignInClient;
- }
-
- /**
- * Signs-in into Google Drive by using the SignIn class
- *
- * @see SignIn
- */
- @Override
- public void signIn() {
- mSignInClient.signIn();
- }
-
- /**
- * Determines whether is able to sign-in
- *
- * @return boolean
: 'true' if is user is signed-in, else 'false'
- */
- protected boolean isAbleToSignIn() {
- if (!mSignInClient.isSignedIn()) {
- GoogleSignInAccount latestSignedInAccount = GoogleSignIn
- .getLastSignedInAccount(mDriveContext);
- if (latestSignedInAccount != null) {
- mDriveResourceClient = Drive
- .getDriveResourceClient(mDriveContext, latestSignedInAccount);
- return true;
- } else {
- showMessage(R.string.sign_in_first);
- return false;
- }
- } else
- return true;
- }
-
- /**
- * Sets the DriveResourceClient
for classes that inherit from this
- *
- * @param resourceClient DriveResourceClient
when the user has signed-in
- * @see DriveResourceClient
- */
- @Override
- public void setDriveResourceClient(DriveResourceClient resourceClient) {
- this.mDriveResourceClient = resourceClient;
- }
-
- /**
- * Sets whether the user is or not logged in
- *
- * @param isLoggedIn boolean
, 'true' if signed-in, else 'false'
- */
- @Override
- public void setLoggedIn(boolean isLoggedIn) {
- mSignInClient.setSignedIn(isLoggedIn);
- }
-
- /**
- * Method for not repeating code when showing a Toast
- *
- * @param message String
which contains the message to be shown
- * @see #showMessage(int)
- * @deprecated use {@link #showMessage(int)} instead
- */
- @Override
- @Deprecated
- public void showMessage(@NonNull String message) {
- Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show();
- }
-
- /**
- * Method for not repeating code when showing a Toast
- *
- * @param message @StringRes int
which contains the resource id (R.string
- * .string_name)
- * @see StringRes
- * @see R.string
- */
- @Override
- public void showMessage(@StringRes int message) {
- Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show();
- }
-
- /**
- * Query the files that applies to some filters, saving them to a DataBufferAdapter object
- *
- * @param resultsAdapter DataBufferAdapter of Metadata
which will store the results
- * @see Constants.DRIVE
- * @see Constants.SQL
- * @see DataBufferAdapter
- * @see Metadata
- */
- protected void queryFiles(DataBufferAdapter resultsAdapter) {
- SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE)
- .build();
- Query query = new Query.Builder()
- .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, Constants.SQL.DB_FILENAME),
- Filters.eq(SearchableField.MIME_TYPE, Constants.DRIVE.MIME_TYPE)))
- .setSortOrder(sortOrder)
- .build();
- retrieveContents(query, resultsAdapter);
- }
-
- /**
- * Query only the files that are an IV Vector (for encryption), saving them to a
- * DataBufferAdapter object
- *
- * @param resultsAdapter DataBufferAdapter of Metadata
which will store the results
- * @see Constants.SQL
- * @see Constants.DRIVE
- * @see javax.crypto.Cipher#init(int, Key, AlgorithmParameterSpec)
- * @see java.security.SecureRandom#nextBytes(byte[])
- */
- protected void getIVVector(DataBufferAdapter resultsAdapter) {
- SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE)
- .build();
- Query query = new Query.Builder()
- .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, DRIVE.IV_FILE),
- Filters.eq(SearchableField.MIME_TYPE, DRIVE.IV_MIME_TYPE)))
- .setSortOrder(sortOrder)
- .build();
- retrieveContents(query, resultsAdapter);
- }
-
- /**
- * By providing a query, retrieve the correspondent Google Drive files into an adapter
- *
- * @param query determines which files will be downloaded
- * @param resultsAdapter stores files inside a BufferAdapter
- * @see Query
- * @see DataBufferAdapter
- * @see Metadata
- */
- private void retrieveContents(@NonNull Query query, DataBufferAdapter resultsAdapter) {
- Task appFolderTask = getDriveResourceClient().getAppFolder();
- appFolderTask.addOnSuccessListener(getMainActivity(), driveFolder -> {
- Task queryTask = getDriveResourceClient()
- .queryChildren(driveFolder, query);
- queryTask.addOnSuccessListener(getMainActivity(), resultsAdapter::append);
- });
- }
-}
+package javinator9889.securepass.backup.drive.base;
+
+import android.app.Activity;
+import android.content.Context;
+import android.widget.Toast;
+
+import com.google.android.gms.auth.api.signin.GoogleSignIn;
+import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
+import com.google.android.gms.drive.Drive;
+import com.google.android.gms.drive.DriveFolder;
+import com.google.android.gms.drive.DriveResourceClient;
+import com.google.android.gms.drive.Metadata;
+import com.google.android.gms.drive.MetadataBuffer;
+import com.google.android.gms.drive.query.Filters;
+import com.google.android.gms.drive.query.Query;
+import com.google.android.gms.drive.query.SearchableField;
+import com.google.android.gms.drive.query.SortOrder;
+import com.google.android.gms.drive.query.SortableField;
+import com.google.android.gms.drive.widget.DataBufferAdapter;
+import com.google.android.gms.tasks.Task;
+
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import javinator9889.securepass.R;
+import javinator9889.securepass.backup.drive.ResultsAdapter;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.Constants.DRIVE;
+
+/**
+ * Created by Javinator9889 on 24/04/2018.
+ * Base class for managing Google Drive connections
+ */
+public class GoogleDriveBase implements IDriveBase {
+ private static final String TAG = "drive-base";
+ private Context mDriveContext;
+ private Activity mMainActivity;
+ private DriveResourceClient mDriveResourceClient;
+ private DataBufferAdapter mResultsAdapter;
+ private SignIn mSignInClient;
+
+ /**
+ * Public constructor for base class
+ *
+ * @param driveContext Context
when initializing this class
+ * @param mainActivity Activity
when initializing this class
+ * @see Context
+ * @see Activity
+ */
+ public GoogleDriveBase(@NonNull Context driveContext, @NonNull Activity mainActivity) {
+ this.mDriveContext = driveContext;
+ this.mMainActivity = mainActivity;
+ mSignInClient = SignIn.getInstance(mainActivity, driveContext);
+ mResultsAdapter = new ResultsAdapter(driveContext);
+ }
+
+ /**
+ * Obtains Context
+ *
+ * @return Context
object
+ * @see Context
+ */
+ public Context getDriveContext() {
+ return mDriveContext;
+ }
+
+ /**
+ * Obtains Activity
+ *
+ * @return Activity
object
+ * @see Activity
+ */
+ public Activity getMainActivity() {
+ return mMainActivity;
+ }
+
+ /**
+ * Obtains the ResultsAdapter
+ *
+ * @return DataBufferAdapter of Metadata
object
+ * @see DataBufferAdapter
+ * @see Metadata
+ */
+ public DataBufferAdapter getResultsAdapter() {
+ return mResultsAdapter;
+ }
+
+ /**
+ * Obtains the DriveResourceClient
+ *
+ * @return DriveResourceClient
object
+ * @see DriveResourceClient
+ */
+ public DriveResourceClient getDriveResourceClient() {
+ return mDriveResourceClient;
+ }
+
+ /**
+ * Obtains the SignInClient
+ *
+ * @return SignIn
object
+ * @see SignIn
+ */
+ public SignIn getSignInClient() {
+ return mSignInClient;
+ }
+
+ /**
+ * Signs-in into Google Drive by using the SignIn class
+ *
+ * @see SignIn
+ */
+ @Override
+ public void signIn() {
+ mSignInClient.signIn();
+ }
+
+ /**
+ * Determines whether is able to sign-in
+ *
+ * @return boolean
: 'true' if is user is signed-in, else 'false'
+ */
+ protected boolean isAbleToSignIn() {
+ if (!mSignInClient.isSignedIn()) {
+ GoogleSignInAccount latestSignedInAccount = GoogleSignIn
+ .getLastSignedInAccount(mDriveContext);
+ if (latestSignedInAccount != null) {
+ mDriveResourceClient = Drive
+ .getDriveResourceClient(mDriveContext, latestSignedInAccount);
+ return true;
+ } else {
+ showMessage(R.string.sign_in_first);
+ return false;
+ }
+ } else
+ return true;
+ }
+
+ /**
+ * Sets the DriveResourceClient
for classes that inherit from this
+ *
+ * @param resourceClient DriveResourceClient
when the user has signed-in
+ * @see DriveResourceClient
+ */
+ @Override
+ public void setDriveResourceClient(DriveResourceClient resourceClient) {
+ this.mDriveResourceClient = resourceClient;
+ }
+
+ /**
+ * Sets whether the user is or not logged in
+ *
+ * @param isLoggedIn boolean
, 'true' if signed-in, else 'false'
+ */
+ @Override
+ public void setLoggedIn(boolean isLoggedIn) {
+ mSignInClient.setSignedIn(isLoggedIn);
+ }
+
+ /**
+ * Method for not repeating code when showing a Toast
+ *
+ * @param message String
which contains the message to be shown
+ * @see #showMessage(int)
+ * @deprecated use {@link #showMessage(int)} instead
+ */
+ @Override
+ @Deprecated
+ public void showMessage(@NonNull String message) {
+ Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show();
+ }
+
+ /**
+ * Method for not repeating code when showing a Toast
+ *
+ * @param message @StringRes int
which contains the resource id (R.string
+ * .string_name)
+ * @see StringRes
+ * @see R.string
+ */
+ @Override
+ public void showMessage(@StringRes int message) {
+ Toast.makeText(mDriveContext, message, Toast.LENGTH_LONG).show();
+ }
+
+ /**
+ * Query the files that applies to some filters, saving them to a DataBufferAdapter object
+ *
+ * @param resultsAdapter DataBufferAdapter of Metadata
which will store the results
+ * @see Constants.DRIVE
+ * @see Constants.SQL
+ * @see DataBufferAdapter
+ * @see Metadata
+ */
+ protected void queryFiles(DataBufferAdapter resultsAdapter) {
+ SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE)
+ .build();
+ Query query = new Query.Builder()
+ .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, Constants.SQL.DB_FILENAME),
+ Filters.eq(SearchableField.MIME_TYPE, Constants.DRIVE.MIME_TYPE)))
+ .setSortOrder(sortOrder)
+ .build();
+ retrieveContents(query, resultsAdapter);
+ }
+
+ /**
+ * Query only the files that are an IV Vector (for encryption), saving them to a
+ * DataBufferAdapter object
+ *
+ * @param resultsAdapter DataBufferAdapter of Metadata
which will store the results
+ * @see Constants.SQL
+ * @see Constants.DRIVE
+ * @see javax.crypto.Cipher#init(int, Key, AlgorithmParameterSpec)
+ * @see java.security.SecureRandom#nextBytes(byte[])
+ */
+ protected void getIVVector(DataBufferAdapter resultsAdapter) {
+ SortOrder sortOrder = new SortOrder.Builder().addSortAscending(SortableField.CREATED_DATE)
+ .build();
+ Query query = new Query.Builder()
+ .addFilter(Filters.and(Filters.eq(SearchableField.TITLE, DRIVE.IV_FILE),
+ Filters.eq(SearchableField.MIME_TYPE, DRIVE.IV_MIME_TYPE)))
+ .setSortOrder(sortOrder)
+ .build();
+ retrieveContents(query, resultsAdapter);
+ }
+
+ /**
+ * By providing a query, retrieve the correspondent Google Drive files into an adapter
+ *
+ * @param query determines which files will be downloaded
+ * @param resultsAdapter stores files inside a BufferAdapter
+ * @see Query
+ * @see DataBufferAdapter
+ * @see Metadata
+ */
+ private void retrieveContents(@NonNull Query query, DataBufferAdapter resultsAdapter) {
+ Task appFolderTask = getDriveResourceClient().getAppFolder();
+ appFolderTask.addOnSuccessListener(getMainActivity(), driveFolder -> {
+ Task queryTask = getDriveResourceClient()
+ .queryChildren(driveFolder, query);
+ queryTask.addOnSuccessListener(getMainActivity(), resultsAdapter::append);
+ });
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java
index c18024b..9d11802 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/IDriveBase.java
@@ -1,59 +1,59 @@
-package javinator9889.securepass.backup.drive.base;
-
-import com.google.android.gms.drive.DriveResourceClient;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.StringRes;
-import javinator9889.securepass.R;
-
-/**
- * Interface for accessing the GoogleDriveBase
class
- * Created by Javinator9889 on 24/04/2018.
- */
-public interface IDriveBase {
- int REQUEST_CODE_SIGN_IN = 0;
-
- int REQUEST_CODE_OPEN_ITEM = 1;
-
- /**
- * Signs-in into Google Drive by using the SignIn class
- *
- * @see SignIn
- */
- void signIn();
-
- /**
- * Sets the DriveResourceClient
for classes that inherit from this
- *
- * @param resourceClient DriveResourceClient
when the user has signed-in
- * @see DriveResourceClient
- */
- void setDriveResourceClient(DriveResourceClient resourceClient);
-
- /**
- * Sets whether the user is or not logged in
- *
- * @param isLoggedIn boolean
, 'true' if signed-in, else 'false'
- */
- void setLoggedIn(boolean isLoggedIn);
-
- /**
- * Method for not repeating code when showing a Toast
- *
- * @param message String
which contains the message to be shown
- * @see #showMessage(int)
- * @deprecated use {@link #showMessage(int)} instead
- */
- @Deprecated
- void showMessage(@NonNull String message);
-
- /**
- * Method for not repeating code when showing a Toast
- *
- * @param message @StringRes int
which contains the resource id (R.string
- * .string_name)
- * @see StringRes
- * @see R.string
- */
- void showMessage(@StringRes int message);
-}
+package javinator9889.securepass.backup.drive.base;
+
+import com.google.android.gms.drive.DriveResourceClient;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import javinator9889.securepass.R;
+
+/**
+ * Interface for accessing the GoogleDriveBase
class
+ * Created by Javinator9889 on 24/04/2018.
+ */
+public interface IDriveBase {
+ int REQUEST_CODE_SIGN_IN = 0;
+
+ int REQUEST_CODE_OPEN_ITEM = 1;
+
+ /**
+ * Signs-in into Google Drive by using the SignIn class
+ *
+ * @see SignIn
+ */
+ void signIn();
+
+ /**
+ * Sets the DriveResourceClient
for classes that inherit from this
+ *
+ * @param resourceClient DriveResourceClient
when the user has signed-in
+ * @see DriveResourceClient
+ */
+ void setDriveResourceClient(DriveResourceClient resourceClient);
+
+ /**
+ * Sets whether the user is or not logged in
+ *
+ * @param isLoggedIn boolean
, 'true' if signed-in, else 'false'
+ */
+ void setLoggedIn(boolean isLoggedIn);
+
+ /**
+ * Method for not repeating code when showing a Toast
+ *
+ * @param message String
which contains the message to be shown
+ * @see #showMessage(int)
+ * @deprecated use {@link #showMessage(int)} instead
+ */
+ @Deprecated
+ void showMessage(@NonNull String message);
+
+ /**
+ * Method for not repeating code when showing a Toast
+ *
+ * @param message @StringRes int
which contains the resource id (R.string
+ * .string_name)
+ * @see StringRes
+ * @see R.string
+ */
+ void showMessage(@StringRes int message);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java
similarity index 97%
rename from APP/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java
index 3388b3e..9ee6f7c 100644
--- a/APP/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/backup/drive/base/SignIn.java
@@ -1,134 +1,134 @@
-package javinator9889.securepass.backup.drive.base;
-
-import android.app.Activity;
-import android.content.Context;
-
-import com.google.android.gms.auth.api.signin.GoogleSignIn;
-import com.google.android.gms.auth.api.signin.GoogleSignInClient;
-import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
-import com.google.android.gms.drive.Drive;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.objects.GeneralObjectContainer;
-import javinator9889.securepass.objects.ObjectContainer;
-
-/**
- * Singleton class for singing-in into Google Drive
- * Created by Javinator9889 on 25/04/2018.
- */
-public class SignIn {
- private static final int REQUEST_CODE_SIGN_IN = 0;
- private static SignIn INSTANCE = null;
- private GeneralObjectContainer mActivityContainer;
- private GeneralObjectContainer mContextContainer;
- private boolean mIsSignedIn;
- private boolean mIsSignInClientBuilt;
- private GoogleSignInClient mGoogleSignInClient;
-
- /**
- * Generates the SignIn
instance the first time it is executed
- *
- * Stores Activity
and Context
into
- * ObjectContainer
for avoiding memory leaks
- *
- *
- * @param mainActivity Activity
when the class was launched
- * @param driveContext Context
when the class was launched
- * @see Activity
- * @see Context
- * @see ObjectContainer
- * @see GeneralObjectContainer
- */
- private SignIn(@NonNull Activity mainActivity, @NonNull Context driveContext) {
- INSTANCE = this;
- this.mActivityContainer = new ObjectContainer<>(mainActivity);
- this.mContextContainer = new ObjectContainer<>(driveContext);
- this.mIsSignedIn = false;
- this.mIsSignInClientBuilt = false;
- }
-
- /**
- * Accessible method for obtaining a SignIn
class instance
- *
- * Stores Activity
and Context
into
- * ObjectContainer
for avoiding memory leaks
- *
- *
- * @param mainActivity Activity
when the class was launched
- * @param driveContext Context
when the class was launched
- * @return SignIn instance if available, else new instance
- * @see Activity
- * @see Context
- * @see ObjectContainer
- * @see GeneralObjectContainer
- */
- public static SignIn getInstance(@NonNull Activity mainActivity,
- @NonNull Context driveContext) {
- return INSTANCE != null ? INSTANCE : new SignIn(mainActivity, driveContext);
- }
-
- /**
- * Signs-in into Google Drive by requesting the user some credentials
- *
- * @see GoogleSignInClient
- * @see #buildGoogleSignInClient()
- */
- public void signIn() {
- Activity mainActivity = mActivityContainer.getLatestStoredObject();
- if (mIsSignInClientBuilt)
- mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(),
- REQUEST_CODE_SIGN_IN);
- else {
- buildGoogleSignInClient();
- mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(),
- REQUEST_CODE_SIGN_IN);
- }
- }
-
- /**
- * Generates the Google Drive sign in client, necessary for accessing to the Google Drive API
- * at the app folder with the chosen account
- *
- * @see GoogleSignIn
- * @see GoogleSignInOptions
- */
- private void buildGoogleSignInClient() {
- Context driveContext = mContextContainer.getLatestStoredObject();
- GoogleSignInOptions signInOptions =
- new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
- .requestScopes(Drive.SCOPE_FILE, Drive.SCOPE_APPFOLDER)
- .build();
- this.mGoogleSignInClient = GoogleSignIn.getClient(driveContext, signInOptions);
- mIsSignInClientBuilt = true;
- }
-
- /**
- * Sets whether the user is or not signed in
- *
- * @param isSignedIn boolean
'true' if already signed-in, else 'false'
- */
- public void setSignedIn(boolean isSignedIn) {
- this.mIsSignedIn = isSignedIn;
- }
-
- /**
- * Checks if user is already signed-in
- *
- * @return boolean 'true' when signed-in, else 'false'
- */
- public boolean isSignedIn() {
- return mIsSignedIn;
- }
-
- /**
- * Finish this class when a new instance is required for some reason
- */
- public void finish() {
- mIsSignedIn = false;
- mIsSignInClientBuilt = false;
- mContextContainer.removeAllObjects();
- mActivityContainer.removeAllObjects();
- mGoogleSignInClient = null;
- INSTANCE = null;
- }
-}
+package javinator9889.securepass.backup.drive.base;
+
+import android.app.Activity;
+import android.content.Context;
+
+import com.google.android.gms.auth.api.signin.GoogleSignIn;
+import com.google.android.gms.auth.api.signin.GoogleSignInClient;
+import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
+import com.google.android.gms.drive.Drive;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+
+/**
+ * Singleton class for singing-in into Google Drive
+ * Created by Javinator9889 on 25/04/2018.
+ */
+public class SignIn {
+ private static final int REQUEST_CODE_SIGN_IN = 0;
+ private static SignIn INSTANCE = null;
+ private GeneralObjectContainer mActivityContainer;
+ private GeneralObjectContainer mContextContainer;
+ private boolean mIsSignedIn;
+ private boolean mIsSignInClientBuilt;
+ private GoogleSignInClient mGoogleSignInClient;
+
+ /**
+ * Generates the SignIn
instance the first time it is executed
+ *
+ * Stores Activity
and Context
into
+ * ObjectContainer
for avoiding memory leaks
+ *
+ *
+ * @param mainActivity Activity
when the class was launched
+ * @param driveContext Context
when the class was launched
+ * @see Activity
+ * @see Context
+ * @see ObjectContainer
+ * @see GeneralObjectContainer
+ */
+ private SignIn(@NonNull Activity mainActivity, @NonNull Context driveContext) {
+ INSTANCE = this;
+ this.mActivityContainer = new ObjectContainer<>(mainActivity);
+ this.mContextContainer = new ObjectContainer<>(driveContext);
+ this.mIsSignedIn = false;
+ this.mIsSignInClientBuilt = false;
+ }
+
+ /**
+ * Accessible method for obtaining a SignIn
class instance
+ *
+ * Stores Activity
and Context
into
+ * ObjectContainer
for avoiding memory leaks
+ *
+ *
+ * @param mainActivity Activity
when the class was launched
+ * @param driveContext Context
when the class was launched
+ * @return SignIn instance if available, else new instance
+ * @see Activity
+ * @see Context
+ * @see ObjectContainer
+ * @see GeneralObjectContainer
+ */
+ public static SignIn getInstance(@NonNull Activity mainActivity,
+ @NonNull Context driveContext) {
+ return INSTANCE != null ? INSTANCE : new SignIn(mainActivity, driveContext);
+ }
+
+ /**
+ * Signs-in into Google Drive by requesting the user some credentials
+ *
+ * @see GoogleSignInClient
+ * @see #buildGoogleSignInClient()
+ */
+ public void signIn() {
+ Activity mainActivity = mActivityContainer.getLatestStoredObject();
+ if (mIsSignInClientBuilt)
+ mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(),
+ REQUEST_CODE_SIGN_IN);
+ else {
+ buildGoogleSignInClient();
+ mainActivity.startActivityForResult(mGoogleSignInClient.getSignInIntent(),
+ REQUEST_CODE_SIGN_IN);
+ }
+ }
+
+ /**
+ * Generates the Google Drive sign in client, necessary for accessing to the Google Drive API
+ * at the app folder with the chosen account
+ *
+ * @see GoogleSignIn
+ * @see GoogleSignInOptions
+ */
+ private void buildGoogleSignInClient() {
+ Context driveContext = mContextContainer.getLatestStoredObject();
+ GoogleSignInOptions signInOptions =
+ new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
+ .requestScopes(Drive.SCOPE_FILE, Drive.SCOPE_APPFOLDER)
+ .build();
+ this.mGoogleSignInClient = GoogleSignIn.getClient(driveContext, signInOptions);
+ mIsSignInClientBuilt = true;
+ }
+
+ /**
+ * Sets whether the user is or not signed in
+ *
+ * @param isSignedIn boolean
'true' if already signed-in, else 'false'
+ */
+ public void setSignedIn(boolean isSignedIn) {
+ this.mIsSignedIn = isSignedIn;
+ }
+
+ /**
+ * Checks if user is already signed-in
+ *
+ * @return boolean 'true' when signed-in, else 'false'
+ */
+ public boolean isSignedIn() {
+ return mIsSignedIn;
+ }
+
+ /**
+ * Finish this class when a new instance is required for some reason
+ */
+ public void finish() {
+ mIsSignedIn = false;
+ mIsSignInClientBuilt = false;
+ mContextContainer.removeAllObjects();
+ mActivityContainer.removeAllObjects();
+ mGoogleSignInClient = null;
+ INSTANCE = null;
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java
similarity index 77%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java
index b5baaae..a0657dd 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ConfigFields.java
@@ -1,152 +1,191 @@
-package javinator9889.securepass.data.configuration;
-
-import java.io.Serializable;
-
-import androidx.annotation.Nullable;
-import javinator9889.securepass.util.values.DatabaseTables;
-
-/**
- * Copyright © 2018 - present | APP by Javinator9889
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see https://www.gnu.org/licenses/.
- *
- * Created by Javinator9889 on 17/10/2018 - APP.
- */
-public abstract class ConfigFields implements IConfigFields, Serializable {
- private long mId;
- private String mDescription;
- private int mSortOrder;
- private long mConfigId;
-
- /**
- * Abstract constructor only visible for inheriting classes
- *
- * @param id config field id
- * @param description optional description
- * @param sortOrder fields sort order
- * @param configId configuration id
- * @see ImagesConfig
- * @see PassConfig
- * @see LongTextConfig
- * @see SmallTextConfig
- */
- ConfigFields(long id, @Nullable String description, int sortOrder,
- long configId) {
- mId = id;
- mDescription = description;
- mSortOrder = sortOrder;
- mConfigId = configId;
- }
-
- /**
- * Obtains current configuration ID (the same as in the database)
- *
- * @return long corresponding the ID
- */
- @Override
- public long getConfigId() {
- return mConfigId;
- }
-
- /**
- * Obtains current description (the same as in the database)
- *
- * @return String corresponding the description (may be null)
- */
- @Override
- @Nullable
- public String getDescription() {
- return mDescription;
- }
-
- /**
- * Obtains current sort order (the same as in the database)
- *
- * @return int corresponding the sort order
- */
- @Override
- public int getSortOrder() {
- return mSortOrder;
- }
-
- /**
- * Sets current configuration ID (the same as in the database)
- *
- * @param id long which must exists at configurations IDs
- */
- @Override
- public void setConfigId(long id) {
- this.mConfigId = id;
- }
-
- /**
- * Sets current description (the same as in the database)
- *
- * @param description nullable String which contains the description
- */
- @Override
- public void setDescription(@Nullable String description) {
- this.mDescription = description;
- }
-
- /**
- * Sets current sort order (the same as in the database)
- *
- * @param index int which correspondents the order inside the fields objects
- */
- @Override
- public void setSortOrder(int index) {
- this.mSortOrder = index;
- }
-
- /**
- * Gets current field ID (the same as in the database) - cannot be changed
- *
- * @return long corresponding the ID
- */
- @Override
- public long getFieldId() {
- return mId;
- }
-
- /**
- * Changes field ID if there is any reason for
- *
- * @param id long corresponding the new ID
- */
- @Override
- public void setFieldId(long id) {
- this.mId = id;
- }
-
- /**
- * Gets the proper table name - names available at
- * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
- *
- * @return String which is the table name
- * @see javinator9889.securepass.util.values.Constants.SQL
- */
- @Override
- public abstract String getTableName();
-
- /**
- * Gets the proper database type - types available at
- * {@link DatabaseTables DatabaseTables enum} types
- *
- * @return DatabaseTables object with the correspondent type
- * @see DatabaseTables
- */
- @Override
- public abstract DatabaseTables getTableType();
-}
+package javinator9889.securepass.data.configuration;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.util.values.DatabaseTables;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 17/10/2018 - APP.
+ */
+public abstract class ConfigFields implements IConfigFields, Serializable {
+ private long mId;
+ private String mDescription;
+ private int mSortOrder;
+ private long mConfigId;
+
+ /**
+ * Abstract constructor only visible for inheriting classes
+ *
+ * @param id config field id
+ * @param description optional description
+ * @param sortOrder fields sort order
+ * @param configId configuration id
+ * @see ImagesConfig
+ * @see PassConfig
+ * @see LongTextConfig
+ * @see SmallTextConfig
+ */
+ ConfigFields(long id, @Nullable String description, int sortOrder,
+ long configId) {
+ mId = id;
+ mDescription = description;
+ mSortOrder = sortOrder;
+ mConfigId = configId;
+ }
+
+ /**
+ * Obtains current configuration ID (the same as in the database)
+ *
+ * @return long corresponding the ID
+ */
+ @Override
+ public long getConfigId() {
+ return mConfigId;
+ }
+
+ /**
+ * Obtains current description (the same as in the database)
+ *
+ * @return String corresponding the description (may be null)
+ */
+ @Override
+ @Nullable
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Obtains current sort order (the same as in the database)
+ *
+ * @return int corresponding the sort order
+ */
+ @Override
+ public int getSortOrder() {
+ return mSortOrder;
+ }
+
+ /**
+ * Sets current configuration ID (the same as in the database)
+ *
+ * @param id long which must exists at configurations IDs
+ */
+ @Override
+ public void setConfigId(long id) {
+ this.mConfigId = id;
+ }
+
+ /**
+ * Sets current description (the same as in the database)
+ *
+ * @param description nullable String which contains the description
+ */
+ @Override
+ public void setDescription(@Nullable String description) {
+ this.mDescription = description;
+ }
+
+ /**
+ * Sets current sort order (the same as in the database)
+ *
+ * @param index int which correspondents the order inside the fields objects
+ */
+ @Override
+ public void setSortOrder(int index) {
+ this.mSortOrder = index;
+ }
+
+ /**
+ * Gets current field ID (the same as in the database) - cannot be changed
+ *
+ * @return long corresponding the ID
+ */
+ @Override
+ public long getFieldId() {
+ return mId;
+ }
+
+ /**
+ * Changes field ID if there is any reason for
+ *
+ * @param id long corresponding the new ID
+ */
+ @Override
+ public void setFieldId(long id) {
+ this.mId = id;
+ }
+
+
+ /**
+ * Gets the proper table name - names available at
+ * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
+ *
+ * @return String which is the table name
+ * @see javinator9889.securepass.util.values.Constants.SQL
+ */
+ @Override
+ public abstract String getTableName();
+
+ /**
+ * Gets the proper database type - types available at
+ * {@link DatabaseTables DatabaseTables enum} types
+ *
+ * @return DatabaseTables object with the correspondent type
+ * @see DatabaseTables
+ */
+ @Override
+ public abstract DatabaseTables getTableType();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ConfigFields that = (ConfigFields) o;
+ return mId == that.mId &&
+ mSortOrder == that.mSortOrder &&
+ mConfigId == that.mConfigId &&
+ Objects.equals(mDescription, that.mDescription);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mDescription, mSortOrder, mConfigId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @NonNull
+ @Override
+ public String toString() {
+ return getTableName() + ":\n" +
+ "{ ID: " + getFieldId() + ",\n" +
+ " Description: " + getDescription() + ",\n" +
+ " Sort order: " + getSortOrder() + ",\n" +
+ " Configuration ID: " + getConfigId() + "}\n";
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java
similarity index 80%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java
index 60559bc..60dfb2e 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/Configuration.java
@@ -1,100 +1,123 @@
-package javinator9889.securepass.data.configuration;
-
-import java.io.Serializable;
-
-import androidx.annotation.Nullable;
-import javinator9889.securepass.objects.GeneralObjectContainer;
-import javinator9889.securepass.objects.ObjectContainer;
-
-/**
- * Class that contains configurations available at class level
- * Created by Javinator9889 on 21/08/2018.
- */
-public class Configuration implements IConfiguration, Serializable {
- private long mId;
- private String mConfigurationName;
- private GeneralObjectContainer mContainer;
-
- /**
- * Public available constructor
- *
- * @param id configuration ID (same as in database)
- * @param configurationName nullable String which has a configuration name
- * @param container nullable container for storing {@link IConfigFields}
- */
- public Configuration(long id,
- @Nullable String configurationName,
- @Nullable GeneralObjectContainer
- container) {
- this.mId = id;
- this.mConfigurationName = configurationName;
- this.mContainer = (container == null) ?
- new ObjectContainer<>() :
- container;
- }
-
- /**
- * Obtains current configuration ID (same as in database)
- *
- * @return long corresponding the current ID
- */
- @Override
- public long getConfigurationId() {
- return mId;
- }
-
- /**
- * Obtains current configuration name (same as in database) - can be null
- *
- * @return String with the name
- */
- @Override
- @Nullable
- public String getConfigurationName() {
- return mConfigurationName;
- }
-
- /**
- * Obtains current configuration fields (same as in database)
- *
- * @return {@link GeneralObjectContainer} of {@link IConfigFields}
- * @see ObjectContainer
- */
- @Override
- public GeneralObjectContainer getConfigFields() {
- return mContainer;
- }
-
- /**
- * Changes configuration ID if needed (it should not be changed)
- *
- * @param id long with the new configuration ID
- */
- @Override
- public void setConfigurationId(long id) {
- this.mId = id;
- }
-
- /**
- * Changes current configuration name (can be null)
- *
- * @param name the new name (or null for no one)
- */
- @Override
- public void setConfigurationName(@Nullable String name) {
- this.mConfigurationName = name;
- }
-
- /**
- * Adds a new {@link IConfigFields configuration} by using the
- * {@link IConfigFields#getSortOrder() field sort order}
- *
- * @param field new configuration to store
- * @see ConfigFields
- */
- @Override
- public void addConfigurationField(IConfigFields field) {
- int position = field.getSortOrder();
- mContainer.storeObject(field, position);
- }
-}
+package javinator9889.securepass.data.configuration;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.Nullable;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+
+/**
+ * Class that contains configurations available at class level
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public class Configuration implements IConfiguration, Serializable {
+ private long mId;
+ private String mConfigurationName;
+ private GeneralObjectContainer mContainer;
+
+ /**
+ * Public available constructor
+ *
+ * @param id configuration ID (same as in database)
+ * @param configurationName nullable String which has a configuration name
+ * @param container nullable container for storing {@link IConfigFields}
+ */
+ public Configuration(long id,
+ @Nullable String configurationName,
+ @Nullable GeneralObjectContainer
+ container) {
+ this.mId = id;
+ this.mConfigurationName = configurationName;
+ this.mContainer = (container == null) ?
+ new ObjectContainer<>() :
+ container;
+ }
+
+ /**
+ * Obtains current configuration ID (same as in database)
+ *
+ * @return long corresponding the current ID
+ */
+ @Override
+ public long getConfigurationId() {
+ return mId;
+ }
+
+ /**
+ * Obtains current configuration name (same as in database) - can be null
+ *
+ * @return String with the name
+ */
+ @Override
+ @Nullable
+ public String getConfigurationName() {
+ return mConfigurationName;
+ }
+
+ /**
+ * Obtains current configuration fields (same as in database)
+ *
+ * @return {@link GeneralObjectContainer} of {@link IConfigFields}
+ * @see ObjectContainer
+ */
+ @Override
+ public GeneralObjectContainer getConfigFields() {
+ return mContainer;
+ }
+
+ /**
+ * Changes configuration ID if needed (it should not be changed)
+ *
+ * @param id long with the new configuration ID
+ */
+ @Override
+ public void setConfigurationId(long id) {
+ this.mId = id;
+ }
+
+ /**
+ * Changes current configuration name (can be null)
+ *
+ * @param name the new name (or null for no one)
+ */
+ @Override
+ public void setConfigurationName(@Nullable String name) {
+ this.mConfigurationName = name;
+ }
+
+ /**
+ * Adds a new {@link IConfigFields configuration} by using the
+ * {@link IConfigFields#getSortOrder() field sort order}
+ *
+ * @param field new configuration to store
+ * @see ConfigFields
+ */
+ @Override
+ public void addConfigurationField(IConfigFields field) {
+ int position = field.getSortOrder();
+ mContainer.storeObject(field, position);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Configuration that = (Configuration) o;
+ return mId == that.mId &&
+ Objects.equals(mConfigurationName, that.mConfigurationName) &&
+ Objects.equals(mContainer, that.mContainer);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mConfigurationName, mContainer);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java
index 475b3fc..c95eaa7 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfigFields.java
@@ -1,83 +1,83 @@
-package javinator9889.securepass.data.configuration;
-
-import javinator9889.securepass.util.values.DatabaseTables;
-
-/**
- * Interface for accessing {@link ConfigFields} methods
- * Created by Javinator9889 on 21/08/2018.
- */
-public interface IConfigFields {
- /**
- * Obtains current configuration ID (the same as in the database)
- *
- * @return long corresponding the ID
- */
- long getConfigId();
-
- /**
- * Obtains current description (the same as in the database)
- *
- * @return String corresponding the description (may be null)
- */
- String getDescription();
-
- /**
- * Obtains current sort order (the same as in the database)
- *
- * @return int corresponding the sort order
- */
- int getSortOrder();
-
- /**
- * Gets the proper table name - names available at
- * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
- *
- * @return String which is the table name
- * @see javinator9889.securepass.util.values.Constants.SQL
- */
- String getTableName();
-
- /**
- * Sets current configuration ID (the same as in the database)
- *
- * @param id long which must exists at configurations IDs
- */
- void setConfigId(long id);
-
- /**
- * Sets current description (the same as in the database)
- *
- * @param description nullable String which contains the description
- */
- void setDescription(String description);
-
- /**
- * Sets current sort order (the same as in the database)
- *
- * @param index int which correspondents the order inside the fields objects
- */
- void setSortOrder(int index);
-
- /**
- * Gets the proper database type - types available at
- * {@link DatabaseTables DatabaseTables enum} types
- *
- * @return DatabaseTables object with the correspondent type
- * @see DatabaseTables
- */
- DatabaseTables getTableType();
-
- /**
- * Gets current field ID (the same as in the database) - cannot be changed
- *
- * @return long corresponding the ID
- */
- long getFieldId();
-
- /**
- * Changes field ID if there is any reason for
- *
- * @param id long corresponding the new ID
- */
- void setFieldId(long id);
-}
+package javinator9889.securepass.data.configuration;
+
+import javinator9889.securepass.util.values.DatabaseTables;
+
+/**
+ * Interface for accessing {@link ConfigFields} methods
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public interface IConfigFields {
+ /**
+ * Obtains current configuration ID (the same as in the database)
+ *
+ * @return long corresponding the ID
+ */
+ long getConfigId();
+
+ /**
+ * Obtains current description (the same as in the database)
+ *
+ * @return String corresponding the description (may be null)
+ */
+ String getDescription();
+
+ /**
+ * Obtains current sort order (the same as in the database)
+ *
+ * @return int corresponding the sort order
+ */
+ int getSortOrder();
+
+ /**
+ * Gets the proper table name - names available at
+ * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
+ *
+ * @return String which is the table name
+ * @see javinator9889.securepass.util.values.Constants.SQL
+ */
+ String getTableName();
+
+ /**
+ * Sets current configuration ID (the same as in the database)
+ *
+ * @param id long which must exists at configurations IDs
+ */
+ void setConfigId(long id);
+
+ /**
+ * Sets current description (the same as in the database)
+ *
+ * @param description nullable String which contains the description
+ */
+ void setDescription(String description);
+
+ /**
+ * Sets current sort order (the same as in the database)
+ *
+ * @param index int which correspondents the order inside the fields objects
+ */
+ void setSortOrder(int index);
+
+ /**
+ * Gets the proper database type - types available at
+ * {@link DatabaseTables DatabaseTables enum} types
+ *
+ * @return DatabaseTables object with the correspondent type
+ * @see DatabaseTables
+ */
+ DatabaseTables getTableType();
+
+ /**
+ * Gets current field ID (the same as in the database) - cannot be changed
+ *
+ * @return long corresponding the ID
+ */
+ long getFieldId();
+
+ /**
+ * Changes field ID if there is any reason for
+ *
+ * @param id long corresponding the new ID
+ */
+ void setFieldId(long id);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java
index 7b1dccb..ee621cf 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/IConfiguration.java
@@ -1,56 +1,56 @@
-package javinator9889.securepass.data.configuration;
-
-import androidx.annotation.Nullable;
-import javinator9889.securepass.objects.GeneralObjectContainer;
-import javinator9889.securepass.objects.ObjectContainer;
-
-/**
- * Created by Javinator9889 on 21/08/2018.
- */
-public interface IConfiguration {
- /**
- * Obtains current configuration ID (same as in database)
- *
- * @return long corresponding the current ID
- */
- long getConfigurationId();
-
- /**
- * Obtains current configuration name (same as in database) - can be null
- *
- * @return String with the name
- */
- @Nullable
- String getConfigurationName();
-
- /**
- * Obtains current configuration fields (same as in database)
- *
- * @return {@link GeneralObjectContainer} of {@link IConfigFields}
- * @see ObjectContainer
- */
- GeneralObjectContainer getConfigFields();
-
- /**
- * Changes configuration ID if needed (it should not be changed)
- *
- * @param id long with the new configuration ID
- */
- void setConfigurationId(long id);
-
- /**
- * Changes current configuration name (can be null)
- *
- * @param name the new name (or null for no one)
- */
- void setConfigurationName(String name);
-
- /**
- * Adds a new {@link IConfigFields configuration} by using the
- * {@link IConfigFields#getSortOrder() field sort order}
- *
- * @param field new configuration to store
- * @see ConfigFields
- */
- void addConfigurationField(IConfigFields field);
-}
+package javinator9889.securepass.data.configuration;
+
+import androidx.annotation.Nullable;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+
+/**
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public interface IConfiguration {
+ /**
+ * Obtains current configuration ID (same as in database)
+ *
+ * @return long corresponding the current ID
+ */
+ long getConfigurationId();
+
+ /**
+ * Obtains current configuration name (same as in database) - can be null
+ *
+ * @return String with the name
+ */
+ @Nullable
+ String getConfigurationName();
+
+ /**
+ * Obtains current configuration fields (same as in database)
+ *
+ * @return {@link GeneralObjectContainer} of {@link IConfigFields}
+ * @see ObjectContainer
+ */
+ GeneralObjectContainer getConfigFields();
+
+ /**
+ * Changes configuration ID if needed (it should not be changed)
+ *
+ * @param id long with the new configuration ID
+ */
+ void setConfigurationId(long id);
+
+ /**
+ * Changes current configuration name (can be null)
+ *
+ * @param name the new name (or null for no one)
+ */
+ void setConfigurationName(String name);
+
+ /**
+ * Adds a new {@link IConfigFields configuration} by using the
+ * {@link IConfigFields#getSortOrder() field sort order}
+ *
+ * @param field new configuration to store
+ * @see ConfigFields
+ */
+ void addConfigurationField(IConfigFields field);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java
similarity index 97%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java
index 57c91ff..6bb3228 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/ImagesConfig.java
@@ -1,58 +1,58 @@
-package javinator9889.securepass.data.configuration;
-
-import androidx.annotation.Nullable;
-import javinator9889.securepass.util.values.Constants.SQL.IMAGES_CONFIG;
-import javinator9889.securepass.util.values.DatabaseTables;
-
-/**
- * Contains available images configurations - uses {@link ConfigFields} methods
- * @see ConfigFields
- * @see IConfigFields
- * Created by Javinator9889 on 21/08/2018.
- */
-public class ImagesConfig extends ConfigFields {
- private static final String TABLE_NAME = IMAGES_CONFIG.NAME;
- private static final DatabaseTables TABLE_TYPE =
- DatabaseTables.IMAGES_CONFIG;
-
- /**
- * Constructor that uses
- * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
- * visible for this classes) - generates ImagesConfig instance
- *
- * @param id config field id
- * @param description optional description
- * @param sortOrder fields sort order
- * @param configId configuration id
- * @see ConfigFields
- * @see IConfigFields
- */
- public ImagesConfig(long id, @Nullable String description, int sortOrder,
- long configId) {
- super(id, description, sortOrder, configId);
- }
-
- /**
- * Gets the proper table name - names available at
- * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
- *
- * @return String which is the table name
- * @see javinator9889.securepass.util.values.Constants.SQL
- */
- @Override
- public String getTableName() {
- return TABLE_NAME;
- }
-
- /**
- * Gets the proper database type - types available at
- * {@link DatabaseTables DatabaseTables enum} types
- *
- * @return DatabaseTables object with the correspondent type
- * @see DatabaseTables
- */
- @Override
- public DatabaseTables getTableType() {
- return TABLE_TYPE;
- }
-}
+package javinator9889.securepass.data.configuration;
+
+import androidx.annotation.Nullable;
+import javinator9889.securepass.util.values.Constants.SQL.IMAGES_CONFIG;
+import javinator9889.securepass.util.values.DatabaseTables;
+
+/**
+ * Contains available images configurations - uses {@link ConfigFields} methods
+ * @see ConfigFields
+ * @see IConfigFields
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public class ImagesConfig extends ConfigFields {
+ private static final String TABLE_NAME = IMAGES_CONFIG.NAME;
+ private static final DatabaseTables TABLE_TYPE =
+ DatabaseTables.IMAGES_CONFIG;
+
+ /**
+ * Constructor that uses
+ * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
+ * visible for this classes) - generates ImagesConfig instance
+ *
+ * @param id config field id
+ * @param description optional description
+ * @param sortOrder fields sort order
+ * @param configId configuration id
+ * @see ConfigFields
+ * @see IConfigFields
+ */
+ public ImagesConfig(long id, @Nullable String description, int sortOrder,
+ long configId) {
+ super(id, description, sortOrder, configId);
+ }
+
+ /**
+ * Gets the proper table name - names available at
+ * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
+ *
+ * @return String which is the table name
+ * @see javinator9889.securepass.util.values.Constants.SQL
+ */
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Gets the proper database type - types available at
+ * {@link DatabaseTables DatabaseTables enum} types
+ *
+ * @return DatabaseTables object with the correspondent type
+ * @see DatabaseTables
+ */
+ @Override
+ public DatabaseTables getTableType() {
+ return TABLE_TYPE;
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java
index 3b663b3..7edb3d1 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/LongTextConfig.java
@@ -1,56 +1,56 @@
-package javinator9889.securepass.data.configuration;
-
-import androidx.annotation.Nullable;
-
-import javinator9889.securepass.util.values.Constants.SQL.LONG_TEXT_CONFIG;
-import javinator9889.securepass.util.values.DatabaseTables;
-
-/**
- * Created by Javinator9889 on 21/08/2018.
- */
-public class LongTextConfig extends ConfigFields {
- private static final String TABLE_NAME = LONG_TEXT_CONFIG.NAME;
- private static final DatabaseTables TABLE_TYPE =
- DatabaseTables.LONG_TEXT_CONFIG;
-
- /**
- * Constructor that uses
- * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
- * visible for this classes) - generates LongTextConfig instance
- *
- * @param id config field id
- * @param description optional description
- * @param sortOrder fields sort order
- * @param configId configuration id
- * @see ConfigFields
- * @see IConfigFields
- */
- public LongTextConfig(long id, @Nullable String description, int sortOrder,
- long configId) {
- super(id, description, sortOrder, configId);
- }
-
- /**
- * Gets the proper table name - names available at
- * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
- *
- * @return String which is the table name
- * @see javinator9889.securepass.util.values.Constants.SQL
- */
- @Override
- public String getTableName() {
- return TABLE_NAME;
- }
-
- /**
- * Gets the proper database type - types available at
- * {@link DatabaseTables DatabaseTables enum} types
- *
- * @return DatabaseTables object with the correspondent type
- * @see DatabaseTables
- */
- @Override
- public DatabaseTables getTableType() {
- return TABLE_TYPE;
- }
-}
+package javinator9889.securepass.data.configuration;
+
+import androidx.annotation.Nullable;
+
+import javinator9889.securepass.util.values.Constants.SQL.LONG_TEXT_CONFIG;
+import javinator9889.securepass.util.values.DatabaseTables;
+
+/**
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public class LongTextConfig extends ConfigFields {
+ private static final String TABLE_NAME = LONG_TEXT_CONFIG.NAME;
+ private static final DatabaseTables TABLE_TYPE =
+ DatabaseTables.LONG_TEXT_CONFIG;
+
+ /**
+ * Constructor that uses
+ * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
+ * visible for this classes) - generates LongTextConfig instance
+ *
+ * @param id config field id
+ * @param description optional description
+ * @param sortOrder fields sort order
+ * @param configId configuration id
+ * @see ConfigFields
+ * @see IConfigFields
+ */
+ public LongTextConfig(long id, @Nullable String description, int sortOrder,
+ long configId) {
+ super(id, description, sortOrder, configId);
+ }
+
+ /**
+ * Gets the proper table name - names available at
+ * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
+ *
+ * @return String which is the table name
+ * @see javinator9889.securepass.util.values.Constants.SQL
+ */
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Gets the proper database type - types available at
+ * {@link DatabaseTables DatabaseTables enum} types
+ *
+ * @return DatabaseTables object with the correspondent type
+ * @see DatabaseTables
+ */
+ @Override
+ public DatabaseTables getTableType() {
+ return TABLE_TYPE;
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java
index 7bf39da..4083235 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/PassConfig.java
@@ -1,56 +1,56 @@
-package javinator9889.securepass.data.configuration;
-
-import androidx.annotation.Nullable;
-
-import javinator9889.securepass.util.values.Constants.SQL.PASS_CONFIG;
-import javinator9889.securepass.util.values.DatabaseTables;
-
-/**
- * Created by Javinator9889 on 21/08/2018.
- */
-public class PassConfig extends ConfigFields {
- private static final String TABLE_NAME = PASS_CONFIG.NAME;
- private static final DatabaseTables TABLE_TYPE =
- DatabaseTables.PASS_CONFIG;
-
- /**
- * Constructor that uses
- * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
- * visible for this classes) - generates PassConfig instance
- *
- * @param id config field id
- * @param description optional description
- * @param sortOrder fields sort order
- * @param configId configuration id
- * @see ConfigFields
- * @see IConfigFields
- */
- public PassConfig(long id, @Nullable String description, int sortOrder,
- long configId) {
- super(id, description, sortOrder, configId);
- }
-
- /**
- * Gets the proper table name - names available at
- * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
- *
- * @return String which is the table name
- * @see javinator9889.securepass.util.values.Constants.SQL
- */
- @Override
- public String getTableName() {
- return TABLE_NAME;
- }
-
- /**
- * Gets the proper database type - types available at
- * {@link DatabaseTables DatabaseTables enum} types
- *
- * @return DatabaseTables object with the correspondent type
- * @see DatabaseTables
- */
- @Override
- public DatabaseTables getTableType() {
- return TABLE_TYPE;
- }
-}
+package javinator9889.securepass.data.configuration;
+
+import androidx.annotation.Nullable;
+
+import javinator9889.securepass.util.values.Constants.SQL.PASS_CONFIG;
+import javinator9889.securepass.util.values.DatabaseTables;
+
+/**
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public class PassConfig extends ConfigFields {
+ private static final String TABLE_NAME = PASS_CONFIG.NAME;
+ private static final DatabaseTables TABLE_TYPE =
+ DatabaseTables.PASS_CONFIG;
+
+ /**
+ * Constructor that uses
+ * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
+ * visible for this classes) - generates PassConfig instance
+ *
+ * @param id config field id
+ * @param description optional description
+ * @param sortOrder fields sort order
+ * @param configId configuration id
+ * @see ConfigFields
+ * @see IConfigFields
+ */
+ public PassConfig(long id, @Nullable String description, int sortOrder,
+ long configId) {
+ super(id, description, sortOrder, configId);
+ }
+
+ /**
+ * Gets the proper table name - names available at
+ * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
+ *
+ * @return String which is the table name
+ * @see javinator9889.securepass.util.values.Constants.SQL
+ */
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Gets the proper database type - types available at
+ * {@link DatabaseTables DatabaseTables enum} types
+ *
+ * @return DatabaseTables object with the correspondent type
+ * @see DatabaseTables
+ */
+ @Override
+ public DatabaseTables getTableType() {
+ return TABLE_TYPE;
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java
similarity index 97%
rename from APP/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java
index 16c1b49..bf074a7 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/configuration/SmallTextConfig.java
@@ -1,55 +1,55 @@
-package javinator9889.securepass.data.configuration;
-
-import androidx.annotation.Nullable;
-
-import javinator9889.securepass.util.values.Constants.SQL.SMALL_TEXT_CONFIG;
-import javinator9889.securepass.util.values.DatabaseTables;
-
-/**
- * Created by Javinator9889 on 21/08/2018.
- */
-public class SmallTextConfig extends ConfigFields {
- private static final String TABLE_NAME = SMALL_TEXT_CONFIG.NAME;
- private static final DatabaseTables TABLE_TYPE = DatabaseTables.SMALL_TEXT;
-
- /**
- * Constructor that uses
- * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
- * visible for this classes) - generates SmallTextConfig instance
- *
- * @param id config field id
- * @param description optional description
- * @param sortOrder fields sort order
- * @param configId configuration id
- * @see ConfigFields
- * @see IConfigFields
- */
- public SmallTextConfig(long id, @Nullable String description, int sortOrder,
- long configId) {
- super(id, description, sortOrder, configId);
- }
-
- /**
- * Gets the proper table name - names available at
- * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
- *
- * @return String which is the table name
- * @see javinator9889.securepass.util.values.Constants.SQL
- */
- @Override
- public String getTableName() {
- return TABLE_NAME;
- }
-
- /**
- * Gets the proper database type - types available at
- * {@link DatabaseTables DatabaseTables enum} types
- *
- * @return DatabaseTables object with the correspondent type
- * @see DatabaseTables
- */
- @Override
- public DatabaseTables getTableType() {
- return TABLE_TYPE;
- }
-}
+package javinator9889.securepass.data.configuration;
+
+import androidx.annotation.Nullable;
+
+import javinator9889.securepass.util.values.Constants.SQL.SMALL_TEXT_CONFIG;
+import javinator9889.securepass.util.values.DatabaseTables;
+
+/**
+ * Created by Javinator9889 on 21/08/2018.
+ */
+public class SmallTextConfig extends ConfigFields {
+ private static final String TABLE_NAME = SMALL_TEXT_CONFIG.NAME;
+ private static final DatabaseTables TABLE_TYPE = DatabaseTables.SMALL_TEXT;
+
+ /**
+ * Constructor that uses
+ * {@link ConfigFields#ConfigFields(long, String, int, long) ConfigFileds constructor} (only
+ * visible for this classes) - generates SmallTextConfig instance
+ *
+ * @param id config field id
+ * @param description optional description
+ * @param sortOrder fields sort order
+ * @param configId configuration id
+ * @see ConfigFields
+ * @see IConfigFields
+ */
+ public SmallTextConfig(long id, @Nullable String description, int sortOrder,
+ long configId) {
+ super(id, description, sortOrder, configId);
+ }
+
+ /**
+ * Gets the proper table name - names available at
+ * {@link javinator9889.securepass.util.values.Constants.SQL SQL names} attributes
+ *
+ * @return String which is the table name
+ * @see javinator9889.securepass.util.values.Constants.SQL
+ */
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Gets the proper database type - types available at
+ * {@link DatabaseTables DatabaseTables enum} types
+ *
+ * @return DatabaseTables object with the correspondent type
+ * @see DatabaseTables
+ */
+ @Override
+ public DatabaseTables getTableType() {
+ return TABLE_TYPE;
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java
similarity index 93%
rename from APP/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java
index 808282e..5fd4d12 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/container/ClassContainer.java
@@ -1,135 +1,135 @@
-package javinator9889.securepass.data.container;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.data.entry.Category;
-import javinator9889.securepass.data.entry.Entry;
-import javinator9889.securepass.data.entry.QRCode;
-import javinator9889.securepass.data.secret.Field;
-import javinator9889.securepass.data.secret.SecurityCode;
-
-/**
- * Created by Javinator9889 on 06/04/2018.
- * CLASS FOR TESTINGS
- */
-public class ClassContainer implements Serializable {
- private List categories;
- private List entries;
- private List qrCodes;
- private List fields;
- private List securityCodes;
- private Map userSharedPreferences;
-
- public ClassContainer(@NonNull List categories,
- @NonNull List entries,
- @NonNull List qrCodes,
- @NonNull List fields,
- @NonNull List securityCodes,
- @NonNull Map userSharedPreferences) {
- this.categories = categories;
- this.entries = entries;
- this.qrCodes = qrCodes;
- this.fields = fields;
- this.securityCodes = securityCodes;
- this.userSharedPreferences = userSharedPreferences;
- }
-
- public ClassContainer(){}
-
- public void setCategories(List categories) {
- this.categories = categories;
- }
-
- public void setEntries(List entries) {
- this.entries = entries;
- }
-
- public void setQrCodes(List qrCodes) {
- this.qrCodes = qrCodes;
- }
-
- public void setFields(List fields) {
- this.fields = fields;
- }
-
- public void setSecurityCodes(List securityCodes) {
- this.securityCodes = securityCodes;
- }
-
- public void setUserSharedPreferences(Map userSharedPreferences) {
- this.userSharedPreferences = userSharedPreferences;
- }
-
-// public void storeDataInDB() {
-// Context appContext = SecurePass.getApplicationInstance().getApplicationContext();
-// String password = IOManager.newInstance(appContext).readPassword();
-// DatabaseManager manager = DatabaseManager.newInstance(appContext, password);
-// CommonOperations operations = CommonOperations.newInstance(manager);
-// for (Category actualCategory : categories)
-// operations.registerNewCategory(actualCategory.getName());
-// for (Entry entry : entries)
-// operations.registerNewAccount(
-// entry.getAccountName(),
-// entry.getAccountPassword(),
-// entry.getIcon(),
-// entry.getDescription(),
-// entry.getCategory().getId());
-// for (QRCode qrCode : qrCodes)
-// operations.registerQRCode(
-// qrCode.getEntry().getId(),
-// qrCode.getName(),
-// qrCode.getDescription(),
-// qrCode.getQrData());
-// for (SecurityCode code : securityCodes)
-// operations.registerNewSecurityCodeSource(code.getAccountName());
-// for (Field field : fields)
-// operations.registerNewFieldForSecurityCodeSource(field.getCode(), field.isCodeUsed(),
-// field.getSecurityCodeID());
-// operations.finishConnection();
-// }
-
- public List getCategories() {
- return categories;
- }
-
- public List getEntries() {
- return entries;
- }
-
- public List getQrCodes() {
- return qrCodes;
- }
-
- public List getFields() {
- return fields;
- }
-
- public List getSecurityCodes() {
- return securityCodes;
- }
-
- public Map getUserSharedPreferences() {
- return userSharedPreferences;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- for (Category category : categories)
- builder.append(category.toString());
- for (Entry entry : entries)
- builder.append(entry.toString());
- for (QRCode qrCode : qrCodes)
- builder.append(qrCode.toString());
- for (Field field : fields)
- builder.append(field.toString());
- for (SecurityCode securityCode : securityCodes)
- builder.append(securityCode.toString());
- builder.append(userSharedPreferences.toString());
- return builder.toString();
- //return super.toString();
- }
-}
+package javinator9889.securepass.data.container;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.data.entry.Category;
+import javinator9889.securepass.data.entry.Entry;
+import javinator9889.securepass.data.entry.QRCode;
+import javinator9889.securepass.data.secret.Field;
+import javinator9889.securepass.data.secret.SecurityCode;
+
+/**
+ * Created by Javinator9889 on 06/04/2018.
+ * CLASS FOR TESTINGS
+ */
+public class ClassContainer implements Serializable {
+ private List categories;
+ private List entries;
+ private List qrCodes;
+ private List fields;
+ private List securityCodes;
+ private Map userSharedPreferences;
+
+ public ClassContainer(@NonNull List categories,
+ @NonNull List entries,
+ @NonNull List qrCodes,
+ @NonNull List fields,
+ @NonNull List securityCodes,
+ @NonNull Map userSharedPreferences) {
+ this.categories = categories;
+ this.entries = entries;
+ this.qrCodes = qrCodes;
+ this.fields = fields;
+ this.securityCodes = securityCodes;
+ this.userSharedPreferences = userSharedPreferences;
+ }
+
+ public ClassContainer(){}
+
+ public void setCategories(List categories) {
+ this.categories = categories;
+ }
+
+ public void setEntries(List entries) {
+ this.entries = entries;
+ }
+
+ public void setQrCodes(List qrCodes) {
+ this.qrCodes = qrCodes;
+ }
+
+ public void setFields(List fields) {
+ this.fields = fields;
+ }
+
+ public void setSecurityCodes(List securityCodes) {
+ this.securityCodes = securityCodes;
+ }
+
+ public void setUserSharedPreferences(Map userSharedPreferences) {
+ this.userSharedPreferences = userSharedPreferences;
+ }
+
+// public void storeDataInDB() {
+// Context appContext = SecurePass.getApplicationInstance().getApplicationContext();
+// String password = IOManager.newInstance(appContext).readPassword();
+// DatabaseManager manager = DatabaseManager.getInstance(appContext, password);
+// CommonOperations operations = CommonOperations.newInstance(manager);
+// for (Category actualCategory : categories)
+// operations.registerNewCategory(actualCategory.getName());
+// for (Entry entry : entries)
+// operations.registerNewAccount(
+// entry.getAccountName(),
+// entry.getAccountPassword(),
+// entry.getIcon(),
+// entry.getDescription(),
+// entry.getCategoryId().getId());
+// for (QRCode qrCode : qrCodes)
+// operations.registerQRCode(
+// qrCode.getEntryId().getId(),
+// qrCode.getName(),
+// qrCode.getDescription(),
+// qrCode.getQrData());
+// for (SecurityCode code : securityCodes)
+// operations.registerNewSecurityCodeSource(code.getAccountName());
+// for (Field field : fields)
+// operations.registerNewFieldForSecurityCodeSource(field.getCode(), field.isCodeUsed(),
+// field.getSecurityCodeID());
+// operations.finishConnection();
+// }
+
+ public List getCategories() {
+ return categories;
+ }
+
+ public List getEntries() {
+ return entries;
+ }
+
+ public List getQrCodes() {
+ return qrCodes;
+ }
+
+ public List getFields() {
+ return fields;
+ }
+
+ public List getSecurityCodes() {
+ return securityCodes;
+ }
+
+ public Map getUserSharedPreferences() {
+ return userSharedPreferences;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ for (Category category : categories)
+ builder.append(category.toString());
+ for (Entry entry : entries)
+ builder.append(entry.toString());
+ for (QRCode qrCode : qrCodes)
+ builder.append(qrCode.toString());
+ for (Field field : fields)
+ builder.append(field.toString());
+ for (SecurityCode securityCode : securityCodes)
+ builder.append(securityCode.toString());
+ builder.append(userSharedPreferences.toString());
+ return builder.toString();
+ //return super.toString();
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/Category.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Category.java
similarity index 61%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/Category.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Category.java
index dd207be..41dde83 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/Category.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Category.java
@@ -1,65 +1,91 @@
-package javinator9889.securepass.data.entry;
-
-import java.io.Serializable;
-
-/**
- * Class for containing categories
- * Created by Javinator9889 on 29/03/2018.
- */
-public class Category implements Serializable {
- private int mId;
- private String mName;
-
- /**
- * Public available constructor for generating Category
- *
- * @param id category ID
- * @param name category name
- */
- public Category(int id, String name) {
- this.mId = id;
- this.mName = name;
- }
-
- /**
- * @deprecated Default constructor - deprecated. Use {@link #Category(int, String)} instead
- */
- @Deprecated
- public Category() {
- this.mId = 0;
- this.mName = "Global";
- }
-
- /**
- * Obtains current category ID
- *
- * @return long
with the ID
- */
- public int getId() {
- return mId;
- }
-
- /**
- * Obtains current category name
- *
- * @return String
with the name
- */
- public String getName() {
- return mName;
- }
-
- /**
- * Updates current category name
- *
- * @param name new name
- */
- public void setName(String name) {
- this.mName = name;
- }
-
- @Override
- public String toString() {
- return "Category ID: " + mId + "\n" +
- "Category name: " + mName + "\n";
- }
-}
+package javinator9889.securepass.data.entry;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Class for containing categories
+ * Created by Javinator9889 on 29/03/2018.
+ */
+public class Category implements Serializable {
+ private long mId;
+ private String mName;
+
+ /**
+ * Public available constructor for generating Category
+ *
+ * @param id category ID
+ * @param name category name
+ */
+ public Category(long id, String name) {
+ this.mId = id;
+ this.mName = name;
+ }
+
+ /**
+ * @deprecated Default constructor - deprecated. Use {@link #Category(long, String)} instead
+ */
+ @Deprecated
+ public Category() {
+ this.mId = 0;
+ this.mName = "Global";
+ }
+
+ /**
+ * Obtains current category ID
+ *
+ * @return long
with the ID
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Obtains current category name
+ *
+ * @return String
with the name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Updates current category name
+ *
+ * @param name new name
+ */
+ public void setName(String name) {
+ this.mName = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "Category ID: " + mId + "\n" +
+ "Category name: " + mName + "\n";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Category category = (Category) o;
+ return mId == category.mId &&
+ Objects.equals(mName, category.mName);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see Objects#hash(Object...)
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mName);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Entry.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Entry.java
new file mode 100644
index 0000000..cb5e51b
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/Entry.java
@@ -0,0 +1,132 @@
+package javinator9889.securepass.data.entry;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Created by Javinator9889 on 29/03/2018.
+ */
+public class Entry implements Serializable {
+ private long mId;
+ private long mCategoryId;
+ private long mConfigId;
+ private String mName;
+ private String mIcon;
+
+ /**
+ * Public constructor declaring only the needed entry params
+ *
+ * @param id entry ID
+ * @param name entry name
+ * @param icon entry icon
+ * @param categoryId entry parent category ID
+ * @param configurationId entry parent configuration ID
+ */
+ public Entry(long id,
+ @NonNull String name,
+ @NonNull String icon,
+ long categoryId,
+ long configurationId) {
+ mId = id;
+ mName = name;
+ mIcon = icon;
+ mCategoryId = categoryId;
+ mConfigId = configurationId;
+ }
+
+ /**
+ * Obtains current entry ID
+ *
+ * @return long
with the ID
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Obtains current entry name
+ *
+ * @return String
with the name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Updates entry name
+ *
+ * @param name new name
+ */
+ public void setName(String name) {
+ this.mName = name;
+ }
+
+ /**
+ * Obtains current entry icon
+ *
+ * @return String
with the icon
+ */
+ public String getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * Sets a new icon for the entry
+ *
+ * @param icon new icon
+ */
+ public void setIcon(String icon) {
+ this.mIcon = icon;
+ }
+
+ /**
+ * Gets current entry category
+ *
+ * @return {@code long} with the category ID
+ */
+ public long getCategoryId() {
+ return mCategoryId;
+ }
+
+ /**
+ * Updates current entry categoryId
+ *
+ * @param categoryId new categoryId
+ */
+ public void setCategoryId(long categoryId) {
+ this.mCategoryId = categoryId;
+ }
+
+ @Override
+ public String toString() {
+ return "Entry ID: " + mId +
+ "\nEntry icon: " + mIcon +
+ "\nEntry name: " + mName +
+ "\nEntry categoryId: " + mCategoryId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Entry entry = (Entry) o;
+ return mId == entry.mId &&
+ mCategoryId == entry.mCategoryId &&
+ mConfigId == entry.mConfigId &&
+ Objects.equals(mName, entry.mName) &&
+ Objects.equals(mIcon, entry.mIcon);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mCategoryId, mConfigId, mName, mIcon);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java
similarity index 60%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java
index 97cc026..34479fd 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/QRCode.java
@@ -1,138 +1,166 @@
-package javinator9889.securepass.data.entry;
-
-import java.io.Serializable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Class containing QRCodes
- * Created by Javinator9889 on 29/03/2018.
- */
-public class QRCode implements Serializable {
- private long mId;
- private String mName;
- private String description;
- private String mQrData;
- private Entry mParentEntry;
-
- /**
- * Public constructor available for generating a new QRCode
- *
- * @param id QRCode ID
- * @param name QRCode name
- * @param description QRCode description
- * @param qrData QRCode data
- * @param parentEntry QRCode parent entry
- */
- public QRCode(long id,
- @NonNull String name,
- @Nullable String description,
- @NonNull String qrData,
- @NonNull Entry parentEntry) {
- this.mId = id;
- this.mName = name;
- this.description = description;
- this.mQrData = qrData;
- this.mParentEntry = parentEntry;
- }
-
- /**
- * Obtains current QRCode ID
- *
- * @return long
with the ID
- */
- public long getId() {
- return mId;
- }
-
- /**
- * Updates current QRCode ID - this method should not be used
- *
- * @param id new ID
- */
- public void setId(long id) {
- this.mId = id;
- }
-
- /**
- * Obtains current QRCode name
- *
- * @return String
with the name
- */
- public String getName() {
- return mName;
- }
-
- /**
- * Updates current QRCode name
- *
- * @param name new name
- */
- public void setName(String name) {
- this.mName = name;
- }
-
- /**
- * Obtains current QRCode description
- *
- * @return String
with the description
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Updates current QRCode description
- *
- * @param description new description
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- * Obtains QRCode data
- *
- * @return String
with data
- */
- public String getQrData() {
- return mQrData;
- }
-
- /**
- * Updates QRCode data
- *
- * @param qrData new data
- */
- public void setQrData(String qrData) {
- this.mQrData = qrData;
- }
-
- /**
- * Obtains QRCode parent entry
- *
- * @return parent Entry
- */
- public Entry getEntry() {
- return mParentEntry;
- }
-
- /**
- * Updates QRCode parent entry
- *
- * @param entry new entry
- */
- public void setEntry(@NonNull Entry entry) {
- this.mParentEntry = entry;
- }
-
- @Override
- public String toString() {
- return "QRCode ID: " + mId +
- "\nQRCode mName: " + mName +
- "\nQRCode description: " + description +
- "\nQRCode data: " + mQrData +
- "\nQRCode entry: " + mParentEntry.toString();
- }
-}
+package javinator9889.securepass.data.entry;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Class containing QRCodes
+ * Created by Javinator9889 on 29/03/2018.
+ */
+public class QRCode implements Serializable {
+ private long mId;
+ private String mName;
+ private String description;
+ private String mQrData;
+ private long mParentEntryId;
+
+ /**
+ * Public constructor available for generating a new QRCode
+ *
+ * @param id QRCode ID
+ * @param name QRCode name
+ * @param description QRCode description
+ * @param qrData QRCode data
+ * @param parentEntryId QRCode parent entry ID
+ */
+ public QRCode(long id,
+ @NonNull String name,
+ @Nullable String description,
+ @NonNull String qrData,
+ long parentEntryId) {
+ this.mId = id;
+ this.mName = name;
+ this.description = description;
+ this.mQrData = qrData;
+ this.mParentEntryId = parentEntryId;
+ }
+
+ /**
+ * Obtains current QRCode ID
+ *
+ * @return long
with the ID
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Updates current QRCode ID - this method should not be used
+ *
+ * @param id new ID
+ */
+ public void setId(long id) {
+ this.mId = id;
+ }
+
+ /**
+ * Obtains current QRCode name
+ *
+ * @return String
with the name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Updates current QRCode name
+ *
+ * @param name new name
+ */
+ public void setName(String name) {
+ this.mName = name;
+ }
+
+ /**
+ * Obtains current QRCode description
+ *
+ * @return String
with the description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Updates current QRCode description
+ *
+ * @param description new description
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Obtains QRCode data
+ *
+ * @return String
with data
+ */
+ public String getQrData() {
+ return mQrData;
+ }
+
+ /**
+ * Updates QRCode data
+ *
+ * @param qrData new data
+ */
+ public void setQrData(String qrData) {
+ this.mQrData = qrData;
+ }
+
+ /**
+ * Obtains QRCode parent entry
+ *
+ * @return parent entry ID
+ */
+ public long getEntryId() {
+ return mParentEntryId;
+ }
+
+ /**
+ * Updates QRCode parent entryId
+ *
+ * @param entryId new entryId
+ */
+ public void setEntryId(@NonNull long entryId) {
+ this.mParentEntryId = entryId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "QRCode ID: " + mId +
+ "\nQRCode name: " + mName +
+ "\nQRCode description: " + description +
+ "\nQRCode data: " + mQrData +
+ "\nQRCode entry ID: " + mParentEntryId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ QRCode qrCode = (QRCode) o;
+ return mId == qrCode.mId &&
+ mParentEntryId == qrCode.mParentEntryId &&
+ Objects.equals(mName, qrCode.mName) &&
+ Objects.equals(description, qrCode.description) &&
+ Objects.equals(mQrData, qrCode.mQrData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mName, description, mQrData, mParentEntryId);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java
similarity index 67%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java
index 1c33026..be2beef 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/ICommonMethods.java
@@ -1,24 +1,38 @@
-package javinator9889.securepass.data.entry.fields;
-
-import androidx.annotation.NonNull;
-
-/**
- * Interface with common methods to {@link Image}, {@link Password}, {@link LongText} and
- * {@link SmallText}
- * Created by Javinator9889 on 16/08/2018.
- */
-public interface ICommonMethods {
- /**
- * Updates the field description by te given one
- *
- * @param fieldDescription new description
- */
- void setFieldDescription(@NonNull String fieldDescription);
-
- /**
- * Obtains the current field description
- *
- * @return String
with the description
- */
- String getFieldDescription();
-}
+package javinator9889.securepass.data.entry.fields;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Interface with common methods to {@link Image}, {@link Password}, {@link LongText} and
+ * {@link SmallText}
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public interface ICommonMethods {
+ /**
+ * Updates the field description by te given one
+ *
+ * @param fieldDescription new description
+ */
+ void setFieldDescription(@NonNull String fieldDescription);
+
+ /**
+ * Obtains the current field description
+ *
+ * @return String
with the description
+ */
+ String getFieldDescription();
+
+ /**
+ * Gets the parent entry ID for this image
+ *
+ * @return {@code long} with the ID
+ */
+ long getEntryId();
+
+ /**
+ * Sets a new image parent entry ID
+ *
+ * @param id new parent entry ID
+ */
+ void setEntryId(long id);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java
similarity index 96%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java
index d3072d0..5647ae1 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IImage.java
@@ -1,39 +1,39 @@
-package javinator9889.securepass.data.entry.fields;
-
-import androidx.annotation.NonNull;
-
-/**
- * Interface for accessing {@link Image} methods
- * Created by Javinator9889 on 16/08/2018.
- */
-public interface IImage extends ICommonMethods {
- /**
- * Saves the image source
- *
- * @param imageSource non null String
containing the Base64 source
- * @see android.util.Base64
- */
- void setImageSource(@NonNull String imageSource);
-
- /**
- * Obtains the image source
- *
- * @return String
containing the Base64 image
- * @see android.util.Base64
- */
- String getImageSource();
-
- /**
- * Obtains the current image ID
- *
- * @return long
corresponding the ID
- */
- long getImageID();
-
- /**
- * Sets a new image ID for any reason - should not be called
- *
- * @param imageID the new ID
- */
- void setImageID(long imageID);
-}
+package javinator9889.securepass.data.entry.fields;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Interface for accessing {@link Image} methods
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public interface IImage extends ICommonMethods {
+ /**
+ * Saves the image source
+ *
+ * @param imageSource non null String
containing the Base64 source
+ * @see android.util.Base64
+ */
+ void setImageSource(@NonNull String imageSource);
+
+ /**
+ * Obtains the image source
+ *
+ * @return String
containing the Base64 image
+ * @see android.util.Base64
+ */
+ String getImageSource();
+
+ /**
+ * Obtains the current image ID
+ *
+ * @return long
corresponding the ID
+ */
+ long getImageID();
+
+ /**
+ * Sets a new image ID for any reason - should not be called
+ *
+ * @param imageID the new ID
+ */
+ void setImageID(long imageID);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java
similarity index 95%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java
index d8e1e5e..89806f4 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IPassword.java
@@ -1,37 +1,37 @@
-package javinator9889.securepass.data.entry.fields;
-
-import androidx.annotation.NonNull;
-
-/**
- * Interface for accessing the {@link Password} methods
- * Created by Javinator9889 on 16/08/2018.
- */
-public interface IPassword extends ICommonMethods {
- /**
- * Sets a new password
- *
- * @param password non null String with the password
- */
- void setPassword(@NonNull String password);
-
- /**
- * Obtains the current stored password
- *
- * @return String
with the password
- */
- String getPassword();
-
- /**
- * Gets the current password ID
- *
- * @return long
with the ID
- */
- long getPasswordID();
-
- /**
- * Sets a new ID - this method should not be called
- *
- * @param passwordID new ID
- */
- void setPasswordID(long passwordID);
-}
+package javinator9889.securepass.data.entry.fields;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Interface for accessing the {@link Password} methods
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public interface IPassword extends ICommonMethods {
+ /**
+ * Sets a new password
+ *
+ * @param password non null String with the password
+ */
+ void setPassword(@NonNull String password);
+
+ /**
+ * Obtains the current stored password
+ *
+ * @return String
with the password
+ */
+ String getPassword();
+
+ /**
+ * Gets the current password ID
+ *
+ * @return long
with the ID
+ */
+ long getPasswordID();
+
+ /**
+ * Sets a new ID - this method should not be called
+ *
+ * @param passwordID new ID
+ */
+ void setPasswordID(long passwordID);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java
similarity index 81%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java
index 8eb9f0a..1e99ada 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/IText.java
@@ -1,51 +1,65 @@
-package javinator9889.securepass.data.entry.fields;
-
-import androidx.annotation.NonNull;
-
-/**
- * Copyright © 2018 - present | APP by Javinator9889
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see https://www.gnu.org/licenses/.
- *
- * Created by Javinator9889 on 26/10/2018 - APP.
- */
-public interface IText extends ICommonMethods {
- /**
- * Sets the new text
- *
- * @param text non null text
- */
- void setText(@NonNull String text);
-
- /**
- * Obtains the current text
- *
- * @return String
with the text
- */
- String getText();
-
- /**
- * Gets the current text ID
- *
- * @return long
with the text
- */
- long getTextID();
-
- /**
- * Sets a new text ID for any reason - this method should not be called
- *
- * @param id the new ID
- */
- void setTextID(long id);
-}
+package javinator9889.securepass.data.entry.fields;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 26/10/2018 - APP.
+ */
+public interface IText extends ICommonMethods {
+ /**
+ * Sets the new text
+ *
+ * @param text non null text
+ */
+ void setText(@NonNull String text);
+
+ /**
+ * Obtains the current text
+ *
+ * @return String
with the text
+ */
+ String getText();
+
+ /**
+ * Gets the current text ID
+ *
+ * @return long
with the text
+ */
+ long getTextID();
+
+ /**
+ * Sets a new text ID for any reason - this method should not be called
+ *
+ * @param id the new ID
+ */
+ void setTextID(long id);
+
+ /**
+ * Gets the order of the text.
+ *
+ * @return {@code int} with the sort order.
+ */
+ int getOrder();
+
+ /**
+ * Sets a new order of the text.
+ *
+ * @param order new text order.
+ */
+ void setOrder(int order);
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java
similarity index 56%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java
index 7856756..2af896b 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Image.java
@@ -1,100 +1,157 @@
-package javinator9889.securepass.data.entry.fields;
-
-
-import java.io.Serializable;
-
-import androidx.annotation.NonNull;
-
-/**
- * Stores Image fields
- * Created by Javinator9889 on 16/08/2018.
- */
-public class Image implements IImage, Serializable {
- private String mSource;
- private long mId;
- private String mFieldDescription;
-
- /**
- * Public available constructor for generating a new instance
- *
- * @param id current image ID
- * @param source Base64 image information
- * @param fieldDescription description
- * @see android.util.Base64
- */
- public Image(long id, @NonNull String source, @NonNull String fieldDescription) {
- this.mId = id;
- this.mSource = source;
- this.mFieldDescription = fieldDescription;
- }
-
- /**
- * Saves the image source
- *
- * @param imageSource non null String
containing the Base64 source
- * @see android.util.Base64
- */
- @Override
- public void setImageSource(@NonNull String imageSource) {
- this.mSource = imageSource;
- }
-
- /**
- * Obtains the image source
- *
- * @return String
containing the Base64 image
- * @see android.util.Base64
- */
- @Override
- public String getImageSource() {
- return mSource;
- }
-
- /**
- * Obtains the current image ID
- *
- * @return long
corresponding the ID
- */
- @Override
- public long getImageID() {
- return mId;
- }
-
- /**
- * Sets a new image ID for any reason - should not be called
- *
- * @param imageID the new ID
- */
- @Override
- public void setImageID(long imageID) {
- this.mId = imageID;
- }
-
- /**
- * Updates the field description by te given one
- *
- * @param fieldDescription new description
- * @see ICommonMethods
- */
- @Override
- public void setFieldDescription(@NonNull String fieldDescription) {
- this.mFieldDescription = fieldDescription;
- }
-
- /**
- * Obtains the current field description
- *
- * @return String
with the description
- * @see ICommonMethods
- */
- @Override
- public String getFieldDescription() {
- return mFieldDescription;
- }
-
- @Override
- public String toString() {
- return "Source: " + getImageSource() + "\nmId: " + getImageID() + "\nField description: "
- + getFieldDescription();
- }
-}
+package javinator9889.securepass.data.entry.fields;
+
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Stores Image fields
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public class Image implements IImage, Serializable {
+ private long mId;
+ private long mParentEntryId;
+ private String mSource;
+ private String mFieldDescription;
+
+ /**
+ * Public available constructor for generating a new instance
+ *
+ * @param id current image ID
+ * @param source Base64 image information
+ * @param fieldDescription description
+ * @see android.util.Base64
+ */
+ public Image(long id,
+ long parentEntryId,
+ @NonNull String source,
+ @NonNull String fieldDescription) {
+ this.mId = id;
+ this.mParentEntryId = parentEntryId;
+ this.mSource = source;
+ this.mFieldDescription = fieldDescription;
+ }
+
+ /**
+ * Saves the image source
+ *
+ * @param imageSource non null String
containing the Base64 source
+ * @see android.util.Base64
+ */
+ @Override
+ public void setImageSource(@NonNull String imageSource) {
+ this.mSource = imageSource;
+ }
+
+ /**
+ * Obtains the image source
+ *
+ * @return String
containing the Base64 image
+ * @see android.util.Base64
+ */
+ @Override
+ public String getImageSource() {
+ return mSource;
+ }
+
+ /**
+ * Obtains the current image ID
+ *
+ * @return long
corresponding the ID
+ */
+ @Override
+ public long getImageID() {
+ return mId;
+ }
+
+ /**
+ * Sets a new image ID for any reason - should not be called
+ *
+ * @param imageID the new ID
+ */
+ @Override
+ public void setImageID(long imageID) {
+ this.mId = imageID;
+ }
+
+ /**
+ * Gets the parent entry ID for this image
+ *
+ * @return {@code long} with the ID
+ */
+ @Override
+ public long getEntryId() {
+ return mParentEntryId;
+ }
+
+ /**
+ * Sets a new image parent entry ID
+ *
+ * @param id new parent entry ID
+ */
+ @Override
+ public void setEntryId(long id) {
+ mParentEntryId = id;
+ }
+
+ /**
+ * Updates the field description by te given one
+ *
+ * @param fieldDescription new description
+ * @see ICommonMethods
+ */
+ @Override
+ public void setFieldDescription(@NonNull String fieldDescription) {
+ this.mFieldDescription = fieldDescription;
+ }
+
+ /**
+ * Obtains the current field description
+ *
+ * @return String
with the description
+ * @see ICommonMethods
+ */
+ @Override
+ public String getFieldDescription() {
+ return mFieldDescription;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @NotNull
+ @Override
+ public String toString() {
+ return "Source: " + getImageSource() +
+ "\nId: " + getImageID() +
+ "\nEntry ID: " + getEntryId() +
+ "\nField description: " + getFieldDescription();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Image image = (Image) o;
+ return mId == image.mId &&
+ mParentEntryId == image.mParentEntryId &&
+ Objects.equals(mSource, image.mSource) &&
+ Objects.equals(mFieldDescription, image.mFieldDescription);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mParentEntryId, mSource, mFieldDescription);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java
new file mode 100644
index 0000000..684b2bf
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/LongText.java
@@ -0,0 +1,43 @@
+package javinator9889.securepass.data.entry.fields;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Serializable;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public class LongText extends Text implements Serializable {
+ /**
+ * Public available constructor that uses
+ * {@link Text#Text(long, long, String, String, int) super}
+ * constructor
+ *
+ * @param id long text ID
+ * @param parentEntryId long parent entry ID
+ * @param text long text text
+ * @param fieldDescription description
+ */
+ public LongText(long id,
+ long parentEntryId,
+ @NonNull String text,
+ @NonNull String fieldDescription,
+ int order) {
+ super(id, parentEntryId, text, fieldDescription, order);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @NotNull
+ @Override
+ public String toString() {
+ return "Text: " + getText() +
+ "\nID: " + getTextID() +
+ "\nField description: " + getFieldDescription() +
+ "\nEntry ID: " + getEntryId() +
+ "\nSort order: " + getOrder();
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java
similarity index 55%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java
index b66f30e..64e6bc0 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Password.java
@@ -1,96 +1,152 @@
-package javinator9889.securepass.data.entry.fields;
-
-import java.io.Serializable;
-
-import androidx.annotation.NonNull;
-
-/**
- * Stores Password fields
- * Created by Javinator9889 on 16/08/2018.
- */
-public class Password implements IPassword, Serializable {
- private long mId;
- private String mPassword;
- private String mFieldDescription;
-
- /**
- * Public available constructor fon generating a new instance
- *
- * @param id password ID
- * @param password current password - cannot be null
- * @param fieldDescription description for this field - cannot be null
- */
- public Password(long id, @NonNull String password, @NonNull String fieldDescription) {
- this.mId = id;
- this.mPassword = password;
- this.mFieldDescription = fieldDescription;
- }
-
- /**
- * Sets a new password
- *
- * @param password non null String with the password
- */
- @Override
- public void setPassword(@NonNull String password) {
- this.mPassword = password;
- }
-
- /**
- * Obtains the current stored password
- *
- * @return String
with the password
- */
- @Override
- public String getPassword() {
- return mPassword;
- }
-
- /**
- * Gets the current password ID
- *
- * @return long
with the ID
- */
- @Override
- public long getPasswordID() {
- return mId;
- }
-
- /**
- * Sets a new ID - this method should not be called
- *
- * @param passwordID new ID
- */
- @Override
- public void setPasswordID(long passwordID) {
- this.mId = passwordID;
- }
-
- /**
- * Updates the field description by te given one
- *
- * @param fieldDescription new description
- * @see ICommonMethods
- */
- @Override
- public void setFieldDescription(@NonNull String fieldDescription) {
- this.mFieldDescription = fieldDescription;
- }
-
- /**
- * Obtains the current field description
- *
- * @return String
with the description
- * @see ICommonMethods
- */
- @Override
- public String getFieldDescription() {
- return mFieldDescription;
- }
-
- @Override
- public String toString() {
- return "Password: " + getPassword() + "\nID: " + getPasswordID() + "\nField description: " +
- getFieldDescription();
- }
-}
+package javinator9889.securepass.data.entry.fields;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Stores Password fields
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public class Password implements IPassword, Serializable {
+ private long mId;
+ private long mParentEntryId;
+ private String mPassword;
+ private String mFieldDescription;
+
+ /**
+ * Public available constructor fon generating a new instance
+ *
+ * @param id password ID
+ * @param password current password - cannot be null
+ * @param fieldDescription description for this field - cannot be null
+ */
+ public Password(long id,
+ long parentEntryId,
+ @NonNull String password,
+ @NonNull String fieldDescription) {
+ this.mId = id;
+ this.mParentEntryId = parentEntryId;
+ this.mPassword = password;
+ this.mFieldDescription = fieldDescription;
+ }
+
+ /**
+ * Sets a new password
+ *
+ * @param password non null String with the password
+ */
+ @Override
+ public void setPassword(@NonNull String password) {
+ this.mPassword = password;
+ }
+
+ /**
+ * Obtains the current stored password
+ *
+ * @return String
with the password
+ */
+ @Override
+ public String getPassword() {
+ return mPassword;
+ }
+
+ /**
+ * Gets the current password ID
+ *
+ * @return long
with the ID
+ */
+ @Override
+ public long getPasswordID() {
+ return mId;
+ }
+
+ /**
+ * Sets a new ID - this method should not be called
+ *
+ * @param passwordID new ID
+ */
+ @Override
+ public void setPasswordID(long passwordID) {
+ this.mId = passwordID;
+ }
+
+ /**
+ * Updates the field description by te given one
+ *
+ * @param fieldDescription new description
+ * @see ICommonMethods
+ */
+ @Override
+ public void setFieldDescription(@NonNull String fieldDescription) {
+ this.mFieldDescription = fieldDescription;
+ }
+
+ /**
+ * Obtains the current field description
+ *
+ * @return String
with the description
+ * @see ICommonMethods
+ */
+ @Override
+ public String getFieldDescription() {
+ return mFieldDescription;
+ }
+
+ /**
+ * Gets the parent entry ID for this image
+ *
+ * @return {@code long} with the ID
+ */
+ @Override
+ public long getEntryId() {
+ return mParentEntryId;
+ }
+
+ /**
+ * Sets a new image parent entry ID
+ *
+ * @param id new parent entry ID
+ */
+ @Override
+ public void setEntryId(long id) {
+ mParentEntryId = id;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @NotNull
+ @Override
+ public String toString() {
+ return "Password: " + getPassword() +
+ "\nID: " + getPasswordID() +
+ "\nField description: " + getFieldDescription();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Password password = (Password) o;
+ return mId == password.mId &&
+ mParentEntryId == password.mParentEntryId &&
+ Objects.equals(mPassword, password.mPassword) &&
+ Objects.equals(mFieldDescription, password.mFieldDescription);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mParentEntryId, mPassword, mFieldDescription);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java
new file mode 100644
index 0000000..a9ca41c
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/SmallText.java
@@ -0,0 +1,43 @@
+package javinator9889.securepass.data.entry.fields;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Serializable;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Created by Javinator9889 on 16/08/2018.
+ */
+public class SmallText extends Text implements Serializable {
+ /**
+ * Public available constructor that uses
+ * {@link Text#Text(long, long, String, String, int) super}
+ * constructor
+ *
+ * @param id long text ID
+ * @param parentEntryId long parent entry ID
+ * @param text long text text
+ * @param fieldDescription description
+ */
+ public SmallText(long id,
+ long parentEntryId,
+ @NonNull String text,
+ @NonNull String fieldDescription,
+ int order) {
+ super(id, parentEntryId, text, fieldDescription, order);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @NotNull
+ @Override
+ public String toString() {
+ return "Text: " + getText() +
+ "\nID: " + getTextID() +
+ "\nField description: " + getFieldDescription() +
+ "\nEntry ID: " + getEntryId() +
+ "\nSort order: " + getOrder();
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java
similarity index 55%
rename from APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java
index 7bf3479..9eadea9 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/entry/fields/Text.java
@@ -1,96 +1,171 @@
-package javinator9889.securepass.data.entry.fields;
-
-import androidx.annotation.NonNull;
-
-/**
- * Copyright © 2018 - present | APP by Javinator9889
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see https://www.gnu.org/licenses/.
- *
- * Created by Javinator9889 on 26/10/2018 - APP.
- */
-public abstract class Text implements IText {
- private long mId;
- private String mText;
- private String mFieldDescription;
-
- /**
- * Constructor only available for inheritance classes
- *
- * @param id the text ID
- * @param text the current text
- * @param fieldDescription description
- */
- Text(long id, @NonNull String text, @NonNull String fieldDescription) {
- mId = id;
- mText = text;
- mFieldDescription = fieldDescription;
- }
-
- /**
- * Sets the new text
- *
- * @param text non null text
- */
- public void setText(@NonNull String text) {
- mText = text;
- }
-
- /**
- * Obtains the current text
- *
- * @return String
with the text
- */
- public String getText() {
- return mText;
- }
-
- /**
- * Gets the current text ID
- *
- * @return long
with the text
- */
- public long getTextID() {
- return mId;
- }
-
- /**
- * Sets a new text ID for any reason - this method should not be called
- *
- * @param id the new ID
- */
- public void setTextID(long id) {
- mId = id;
- }
-
- /**
- * Updates the field description by te given one
- *
- * @param fieldDescription new description
- * @see ICommonMethods
- */
- public void setFieldDescription(@NonNull String fieldDescription) {
- mFieldDescription = fieldDescription;
- }
-
- /**
- * Obtains the current field description
- *
- * @return String
with the description
- * @see ICommonMethods
- */
- public String getFieldDescription() {
- return mFieldDescription;
- }
-}
+package javinator9889.securepass.data.entry.fields;
+
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 26/10/2018 - APP.
+ */
+public abstract class Text implements IText {
+ private long mId;
+ private long mParentEntryId;
+ private String mText;
+ private String mFieldDescription;
+ private int mOrder;
+
+ /**
+ * Constructor only available for inheritance classes
+ *
+ * @param id the text ID
+ * @param text the current text
+ * @param fieldDescription description
+ * @param parentEntryId the parent entry ID
+ * @param order the sort order
+ */
+ Text(long id,
+ long parentEntryId,
+ @NonNull String text,
+ @NonNull String fieldDescription,
+ int order) {
+ mId = id;
+ mParentEntryId = parentEntryId;
+ mText = text;
+
+ mFieldDescription = fieldDescription;
+ mOrder = order;
+ }
+
+ /**
+ * Sets the new text
+ *
+ * @param text non null text
+ */
+ public void setText(@NonNull String text) {
+ mText = text;
+ }
+
+ /**
+ * Obtains the current text
+ *
+ * @return String
with the text
+ */
+ public String getText() {
+ return mText;
+ }
+
+ /**
+ * Gets the current text ID
+ *
+ * @return long
with the text
+ */
+ public long getTextID() {
+ return mId;
+ }
+
+ /**
+ * Sets a new text ID for any reason - this method should not be called
+ *
+ * @param id the new ID
+ */
+ public void setTextID(long id) {
+ mId = id;
+ }
+
+ /**
+ * Updates the field description by te given one
+ *
+ * @param fieldDescription new description
+ * @see ICommonMethods
+ */
+ public void setFieldDescription(@NonNull String fieldDescription) {
+ mFieldDescription = fieldDescription;
+ }
+
+ /**
+ * Obtains the current field description
+ *
+ * @return String
with the description
+ * @see ICommonMethods
+ */
+ public String getFieldDescription() {
+ return mFieldDescription;
+ }
+
+ /**
+ * Gets the parent entry ID for this image
+ *
+ * @return {@code long} with the ID
+ */
+ @Override
+ public long getEntryId() {
+ return mParentEntryId;
+ }
+
+ /**
+ * Sets a new image parent entry ID
+ *
+ * @param id new parent entry ID
+ */
+ @Override
+ public void setEntryId(long id) {
+ mParentEntryId = id;
+ }
+
+ /**
+ * Gets the order of the text.
+ *
+ * @return {@code int} with the sort order.
+ */
+ @Override
+ public int getOrder() {
+ return mOrder;
+ }
+
+ /**
+ * Sets a new order of the text.
+ *
+ * @param order new text order.
+ */
+ @Override
+ public void setOrder(int order) {
+ mOrder = order;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Text text = (Text) o;
+ return mId == text.mId &&
+ mParentEntryId == text.mParentEntryId &&
+ Objects.equals(mText, text.mText) &&
+ Objects.equals(mFieldDescription, text.mFieldDescription);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mParentEntryId, mText, mFieldDescription);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/secret/Field.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/Field.java
similarity index 56%
rename from APP/app/src/main/java/javinator9889/securepass/data/secret/Field.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/secret/Field.java
index b2dcd98..040423e 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/secret/Field.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/Field.java
@@ -1,74 +1,103 @@
-package javinator9889.securepass.data.secret;
-
-import java.io.Serializable;
-
-import androidx.annotation.NonNull;
-
-/**
- * Contains Fields of the {@link SecurityCode} class
- * Created by Javinator9889 on 29/03/2018.
- */
-public class Field implements Serializable {
- private long mId;
- private String mCode;
- private boolean mIsCodeUsed;
- private SecurityCode mFieldOf;
-
- /**
- * Public available constructor for Field
- *
- * @param id field ID
- * @param code field code
- * @param isCodeUsed whether the code has been used or not
- * @param fieldOf {@link SecurityCode} parent
- * @see SecurityCode
- */
- public Field(long id, @NonNull String code, boolean isCodeUsed, @NonNull SecurityCode fieldOf) {
- this.mId = id;
- this.mCode = code;
- this.mIsCodeUsed = isCodeUsed;
- this.mFieldOf = fieldOf;
- }
-
- /**
- * Obtains parent ID
- *
- * @return long
with the parent ID
- */
- public long getSecurityCodeID() {
- return mFieldOf.getId();
- }
-
- /**
- * Obtains field code
- *
- * @return String
with the code
- */
- public String getCode() {
- return mCode;
- }
-
- /**
- * Determine whether the current code has been used
- *
- * @return boolean
, 'true' if used, else 'false'
- */
- public boolean isCodeUsed() {
- return mIsCodeUsed;
- }
-
- /**
- * Gets current field ID
- *
- * @return long
with the ID
- */
- public long getId() {
- return mId;
- }
-
- @Override
- public String toString() {
- return "Field mCode: " + mCode + "\nField is used: " + mIsCodeUsed + "\nField field of: " +
- mFieldOf.toString();
- }
-}
+package javinator9889.securepass.data.secret;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Contains Fields of the {@link SecurityCode} class
+ * Created by Javinator9889 on 29/03/2018.
+ */
+public class Field implements Serializable {
+ private long mId;
+ private String mCode;
+ private boolean mIsCodeUsed;
+ private long mSecurityCodeId;
+
+ /**
+ * Public available constructor for Field
+ *
+ * @param id field ID
+ * @param code field code
+ * @param isCodeUsed whether the code has been used or not
+ * @param securityCodeId security code parent ID
+ * @see SecurityCode
+ */
+ public Field(long id, @NonNull String code, boolean isCodeUsed, long securityCodeId) {
+ this.mId = id;
+ this.mCode = code;
+ this.mIsCodeUsed = isCodeUsed;
+ this.mSecurityCodeId = securityCodeId;
+ }
+
+ /**
+ * Obtains parent ID
+ *
+ * @return long
with the parent ID
+ */
+ public long getSecurityCodeID() {
+ return mSecurityCodeId;
+ }
+
+ /**
+ * Obtains field code
+ *
+ * @return String
with the code
+ */
+ public String getCode() {
+ return mCode;
+ }
+
+ /**
+ * Determine whether the current code has been used
+ *
+ * @return boolean
, 'true' if used, else 'false'
+ */
+ public boolean isCodeUsed() {
+ return mIsCodeUsed;
+ }
+
+ /**
+ * Gets current field ID
+ *
+ * @return long
with the ID
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "Field Code: " + mCode +
+ "\nField ID: " + mId +
+ "\nField is used: " + mIsCodeUsed +
+ "\nField of: " + mSecurityCodeId + "\n";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Field field = (Field) o;
+ return mId == field.mId &&
+ mIsCodeUsed == field.mIsCodeUsed &&
+ mSecurityCodeId == field.mSecurityCodeId &&
+ Objects.equals(mCode, field.mCode);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mCode, mIsCodeUsed, mSecurityCodeId);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java
similarity index 64%
rename from APP/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java
index 1eac8a6..6abba23 100644
--- a/APP/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/data/secret/SecurityCode.java
@@ -1,49 +1,74 @@
-package javinator9889.securepass.data.secret;
-
-import java.io.Serializable;
-
-import androidx.annotation.NonNull;
-
-/**
- * Class that contains Fields with SecurityCodes
- * Created by Javinator9889 on 29/03/2018.
- */
-public class SecurityCode implements Serializable {
- private long mId;
- private String mAccountName;
-
- /**
- * Public available constructor for SecurityCodes
- *
- * @param id SecurityCode ID
- * @param accountName SecurityCode name
- */
- public SecurityCode(long id, @NonNull String accountName) {
- this.mId = id;
- this.mAccountName = accountName;
- }
-
- /**
- * Obtains current ID
- *
- * @return long
with the ID
- */
- public long getId() {
- return mId;
- }
-
- /**
- * Obtains current SecurityCode account name
- *
- * @return String
with the name
- */
- public String getAccountName() {
- return mAccountName;
- }
-
- @Override
- public String toString() {
- return "SecurityCode ID: " + mId +
- "\nSecurityCode account name: " + mAccountName + "\n";
- }
-}
+package javinator9889.securepass.data.secret;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Class that contains Fields with SecurityCodes
+ * Created by Javinator9889 on 29/03/2018.
+ */
+public class SecurityCode implements Serializable {
+ private long mId;
+ private String mAccountName;
+
+ /**
+ * Public available constructor for SecurityCodes
+ *
+ * @param id SecurityCode ID
+ * @param accountName SecurityCode name
+ */
+ public SecurityCode(long id, @NonNull String accountName) {
+ this.mId = id;
+ this.mAccountName = accountName;
+ }
+
+ /**
+ * Obtains current ID
+ *
+ * @return long
with the ID
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Obtains current SecurityCode account name
+ *
+ * @return String
with the name
+ */
+ public String getAccountName() {
+ return mAccountName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "SecurityCode ID: " + mId +
+ "\nSecurityCode account name: " + mAccountName + "\n";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SecurityCode that = (SecurityCode) o;
+ return mId == that.mId &&
+ Objects.equals(mAccountName, that.mAccountName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(mId, mAccountName);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/cipher/NoPrivateKeyException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/cipher/NoPrivateKeyException.java
new file mode 100644
index 0000000..283a8e5
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/cipher/NoPrivateKeyException.java
@@ -0,0 +1,30 @@
+package javinator9889.securepass.errors.cipher;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 11/11/2018 - APP.
+ */
+public class NoPrivateKeyException extends RuntimeException {
+ /**
+ * Constructs a new runtime exception with the specified detail message. The cause is not
+ * initialized, and may subsequently be initialized by a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for later retrieval by the
+ * {@link #getMessage()} method.
+ */
+ public NoPrivateKeyException(String message) {
+ super(message);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/ExecutorNonDefinedException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/ExecutorNonDefinedException.java
new file mode 100644
index 0000000..7e0d086
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/ExecutorNonDefinedException.java
@@ -0,0 +1,33 @@
+package javinator9889.securepass.errors.database;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 01/11/2018 - APP.
+ */
+public class ExecutorNonDefinedException extends RuntimeException {
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ExecutorNonDefinedException(String message) {
+ super(message);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/NoJobsEnqueuedError.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/NoJobsEnqueuedError.java
new file mode 100644
index 0000000..3bd2eb5
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/NoJobsEnqueuedError.java
@@ -0,0 +1,33 @@
+package javinator9889.securepass.errors.database;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class NoJobsEnqueuedError extends RuntimeException {
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public NoJobsEnqueuedError(String message) {
+ super(message);
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/OverriddenMethodsNotDefinedError.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/OverriddenMethodsNotDefinedError.java
new file mode 100644
index 0000000..593bff0
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/database/OverriddenMethodsNotDefinedError.java
@@ -0,0 +1,33 @@
+package javinator9889.securepass.errors.database;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 01/11/2018 - APP.
+ */
+public class OverriddenMethodsNotDefinedError extends RuntimeException {
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public OverriddenMethodsNotDefinedError(String message) {
+ super(message);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveNotAvailableException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveNotAvailableException.java
similarity index 81%
rename from APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveNotAvailableException.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveNotAvailableException.java
index 0e8dcea..42ba358 100644
--- a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveNotAvailableException.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveNotAvailableException.java
@@ -1,13 +1,13 @@
-package javinator9889.securepass.errors;
-
-/**
- * Created by Javinator9889 on 06/04/2018.
- */
-public class GoogleDriveNotAvailableException extends RuntimeException {
- /**
- * {@inheritDoc}
- */
- public GoogleDriveNotAvailableException(String message) {
- super(message);
- }
-}
+package javinator9889.securepass.errors.drive;
+
+/**
+ * Created by Javinator9889 on 06/04/2018.
+ */
+public class GoogleDriveNotAvailableException extends RuntimeException {
+ /**
+ * {@inheritDoc}
+ */
+ public GoogleDriveNotAvailableException(String message) {
+ super(message);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveUnableToOpenFileException.java b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveUnableToOpenFileException.java
similarity index 81%
rename from APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveUnableToOpenFileException.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveUnableToOpenFileException.java
index e945bc6..eee3caf 100644
--- a/APP/app/src/main/java/javinator9889/securepass/errors/GoogleDriveUnableToOpenFileException.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/errors/drive/GoogleDriveUnableToOpenFileException.java
@@ -1,13 +1,13 @@
-package javinator9889.securepass.errors;
-
-/**
- * Created by Javinator9889 on 07/04/2018.
- */
-public class GoogleDriveUnableToOpenFileException extends RuntimeException {
- /**
- * {@inheritDoc}
- */
- public GoogleDriveUnableToOpenFileException(String message) {
- super(message);
- }
-}
+package javinator9889.securepass.errors.drive;
+
+/**
+ * Created by Javinator9889 on 07/04/2018.
+ */
+public class GoogleDriveUnableToOpenFileException extends RuntimeException {
+ /**
+ * {@inheritDoc}
+ */
+ public GoogleDriveUnableToOpenFileException(String message) {
+ super(message);
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/io/IOManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/IOManager.java
similarity index 59%
rename from APP/app/src/main/java/javinator9889/securepass/io/IOManager.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/io/IOManager.java
index ede026d..28d029e 100644
--- a/APP/app/src/main/java/javinator9889/securepass/io/IOManager.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/IOManager.java
@@ -1,263 +1,380 @@
-package javinator9889.securepass.io;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.google.android.gms.common.util.IOUtils;
-import com.google.common.io.Files;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import javinator9889.securepass.R;
-import javinator9889.securepass.util.cipher.PasswordCipher;
-import javinator9889.securepass.util.cipher.PasswordSaver;
-import javinator9889.securepass.util.values.Constants;
-
-/**
- * Created by Javinator9889 on 26/03/2018.
- * Manage inputs-outputs from application
- */
-
-public class IOManager {
- private Context mActivityContext;
- private File mFilesCache;
- private File mDatabasePath;
- private File mDataDir;
-
- /**
- * Private constructor used by {@link #newInstance(Context)} method
- *
- * @param activityContext Context
when instantiated the class
- * @see Context
- * @see File
- */
- private IOManager(@NonNull Context activityContext) {
- this.mActivityContext = activityContext;
- this.mFilesCache = activityContext.getCacheDir();
- this.mDatabasePath = activityContext.getDatabasePath(Constants.SQL.DB_FILENAME);
- this.mDataDir = activityContext.getFilesDir();
- }
-
- /**
- * Public static available constructor for getting IOManager instances. Uses internally
- * {@link #IOManager(Context)}
- *
- * @param activityContext Context
when instantiated the class
- * @return IOManager
generated instance
- * @see Context
- */
- @NonNull
- public static IOManager newInstance(Context activityContext) {
- return new IOManager(activityContext);
- }
-
- /**
- * Checks if there is any IV Vector stored (for encryption/decryption) at cache or data dir
- *
- * @return boolean
'true' if there is any vector, else 'false'
- * @see Context#getCacheDir()
- * @see Context#getDataDir()
- */
- public boolean isAnyIVVectorStored() {
- File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat");
- File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat");
- return cacheFile.exists() || dataFile.exists();
- }
-
- /**
- * Gets IV Vector file description inside the {@link File} object
- *
- * @return File
with IV Vector file data
- * @see Context#getCacheDir()
- * @see Context#getDataDir()
- */
- public File getIVVector() {
- File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat");
- File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat");
- return dataFile.exists() ?
- mDataDir.listFiles((dir, name) -> name.toLowerCase().equals("iv_vector.dat"))[0] :
- cacheFile.listFiles(((dir, name) -> name.toLowerCase().equals("iv_vector.dat")))[0];
- }
-
- /**
- * Stores the IV Vector at the {@link Context#getDataDir() data dir path}
- *
- * @param ivVector the vector (in bytes) which will be stored
- * @throws IOException if it is not possible to write to the file
- * @see Context#getDataDir()
- * @see Files#write(byte[], File)
- */
- public void saveIVVector(byte[] ivVector) throws IOException {
- String filename = mDataDir.getAbsolutePath() + "/iv_vector.dat";
- File outputFile = new File(filename);
- Files.write(ivVector, outputFile);
- }
-
- /**
- * Loads from {@link R.raw raw resources} all the SQL scripts
- *
- * @return a List
of String
with the correspondent scripts
- * @throws IOException when there is no file available
- * @see R.raw
- */
- public List loadSQLScript() throws IOException {
- List result = new ArrayList<>(5);
- int[] sqlScripts = new int[]{R.raw.create_category, R.raw.create_entry, R.raw.create_qrcode,
- R.raw.create_security_code, R.raw.create_field};
- for (int sqlScript : sqlScripts) {
- InputStream sqlScriptInputFile = this.mActivityContext.getResources()
- .openRawResource(sqlScript);
- StringBuilder builder = new StringBuilder();
- BufferedReader sqlStringsInFile = new BufferedReader(
- new InputStreamReader(sqlScriptInputFile));
- String currentLine;
- while ((currentLine = sqlStringsInFile.readLine()) != null)
- builder.append(currentLine).append("\n");
- result.add(builder.toString());
- }
- return result;
- }
-
- /**
- * Loads from {@link R.raw raw resources} the privacy text saved as Markdown file
- *
- * @return String
with the hole text
- * @throws IOException when there is no file available
- */
- public String loadPrivacyTextMD() throws IOException {
- InputStream privacyPolicyInputStream = this.mActivityContext.getResources()
- .openRawResource(R.raw.privacy);
- StringBuilder builder = new StringBuilder();
- BufferedReader reader = new BufferedReader(new InputStreamReader(privacyPolicyInputStream));
- String currentLine;
- while ((currentLine = reader.readLine()) != null)
- builder.append(currentLine).append("\n");
- return builder.toString();
- }
-
- /**
- * Loads from {@link R.raw raw resources} the terms and conditions text saved as
- * Markdown
- * file
- *
- * @return String
with the hole text
- * @throws IOException when there is no file available
- */
- public String loadTermsConditionsTextMD() throws IOException {
- InputStream termsConditionsStream = this.mActivityContext.getResources()
- .openRawResource(R.raw.terms_conditions);
- StringBuilder builder = new StringBuilder();
- BufferedReader reader = new BufferedReader(new InputStreamReader(termsConditionsStream));
- String currentLine;
- while ((currentLine = reader.readLine()) != null)
- builder.append(currentLine).append("\n");
- return builder.toString();
- }
-
- /**
- * Stores a password in {@link com.chamber.java.library.SharedChamber}
- *
- * @param userPassword password to save
- * @deprecated method as the password is no longer saved in a file
- */
- @Deprecated
- public void storePassword(@NonNull String userPassword) {
- PasswordCipher passwordSaver = PasswordSaver.instantiate(mActivityContext);
- passwordSaver.putPassword(userPassword);
- }
-
- /**
- * Reads password from {@link com.chamber.java.library.SharedChamber}
- *
- * @return String
with the password
- * @deprecated method as the password is no longer saved in a file
- */
- @Deprecated
- @Nullable
- public String readPassword() {
- PasswordCipher passwordReader = PasswordSaver.instantiate(mActivityContext);
- return passwordReader.getPassword();
- }
-
- /**
- * Writes an InputStream with a database backup to an OutputStream
- *
- * @param from source
- * @deprecated everything is now done at
- * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
- */
- @Deprecated
- public void writeDownloadedDatabaseBackup(@NonNull InputStream from) {
- String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db";
- try {
- OutputStream to = new FileOutputStream(filename);
- IOUtils.copyStream(from, to);
- } catch (IOException e) {
- Log.e("Copy IO", "There was an error while trying to copy the InputStream" +
- " to an OutputStream. Full trace: ", e);
- }
- }
-
- /**
- * Reads a downloaded database backup from FilesCache
- *
- * @return InputStream
when file is available
- * @deprecated everything is now done at
- * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
- */
- @Deprecated
- public InputStream readDownloadedDatabaseBackup() {
- String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db";
- try {
- return new FileInputStream(filename);
- } catch (FileNotFoundException e) {
- Log.e("Read class", "File not found when trying to recover. Full trace: ", e);
- return null;
- }
- }
-
- /**
- * Obtains the path where databases backups are saved temporally
- *
- * @return String
with the path
- */
- public String downloadedDatabaseBackupPath() {
- return mFilesCache.getAbsolutePath() + "/SecurePass.db";
- }
-
- /**
- * Removes downloaded database backup
- *
- * @deprecated everything is now done at
- * {@link javinator9889.securepass.backup.drive.DriveDownloader DriveDownloader} class
- */
- @Deprecated
- public void deleteDownloadedDatabaseBackup() {
- String filename = mFilesCache.getAbsolutePath() + "/class.bck";
-
- File fileToDelete = new File(filename);
- if (!fileToDelete.delete())
- Log.e("Delete IO", "There was an error while trying to delete class.bck");
- }
-
- /**
- * Obtains the path where database is stored
- *
- * @return File
with the path
- */
- public File getDatabasePath() {
- return mDatabasePath;
- }
-}
+package javinator9889.securepass.io;
+
+import android.content.Context;
+import android.util.Base64;
+import android.util.Log;
+
+import com.github.javinator9889.exporter.FileToBytesExporter;
+import com.google.android.gms.common.util.IOUtils;
+import com.google.common.io.Files;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.UnrecoverableEntryException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.R;
+import javinator9889.securepass.util.cipher.PasswordSaver;
+import javinator9889.securepass.util.cipher.keystore.IPasswordCipher;
+import javinator9889.securepass.util.cipher.keystore.PasswordCipher;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Created by Javinator9889 on 26/03/2018. Manage inputs-outputs from application
+ */
+
+public class IOManager {
+ private Context mActivityContext;
+ private File mFilesCache;
+ private File mDatabasePath;
+ private File mDataDir;
+
+ /**
+ * Private constructor used by {@link #newInstance(Context)} method
+ *
+ * @param activityContext Context
when instantiated the class
+ *
+ * @see Context
+ * @see File
+ */
+ private IOManager(@NonNull Context activityContext) {
+ this.mActivityContext = activityContext;
+ this.mFilesCache = activityContext.getCacheDir();
+ this.mDatabasePath = activityContext.getDatabasePath(Constants.SQL.DB_FILENAME);
+ this.mDataDir = activityContext.getFilesDir();
+ }
+
+ /**
+ * Public static available constructor for getting IOManager instances. Uses internally {@link
+ * #IOManager(Context)}
+ *
+ * @param activityContext Context
when instantiated the class
+ *
+ * @return IOManager
generated instance
+ *
+ * @see Context
+ */
+ @NonNull
+ public static IOManager newInstance(@NonNull Context activityContext) {
+ return new IOManager(activityContext);
+ }
+
+ /**
+ * Checks if there is any IV Vector stored (for encryption/decryption) at cache or data dir
+ *
+ * @return boolean
'true' if there is any vector, else 'false'
+ *
+ * @see Context#getCacheDir()
+ * @see Context#getDataDir()
+ */
+ public boolean isAnyIVVectorStored() {
+ File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat");
+ File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat");
+ return cacheFile.exists() || dataFile.exists();
+ }
+
+ /**
+ * Gets IV Vector file description inside the {@link File} object
+ *
+ * @return File
with IV Vector file data
+ *
+ * @see Context#getCacheDir()
+ * @see Context#getDataDir()
+ */
+ public File getIVVector() {
+ File cacheFile = new File(mFilesCache.getAbsolutePath() + "/iv_vector.dat");
+ File dataFile = new File(mDataDir.getAbsolutePath() + "/iv_vector.dat");
+ return dataFile.exists() ?
+ mDataDir.listFiles((dir, name) -> name.toLowerCase().equals("iv_vector.dat"))[0] :
+ cacheFile.listFiles(((dir, name) -> name.toLowerCase().equals("iv_vector.dat")))[0];
+ }
+
+ /**
+ * Stores the IV Vector at the {@link Context#getDataDir() data dir path}
+ *
+ * @param ivVector the vector (in bytes) which will be stored
+ *
+ * @throws IOException if it is not possible to write to the file
+ * @see Context#getDataDir()
+ * @see Files#write(byte[], File)
+ */
+ public void saveIVVector(byte[] ivVector) throws IOException {
+ String filename = mDataDir.getAbsolutePath() + "/iv_vector.dat";
+ File outputFile = new File(filename);
+ Files.write(ivVector, outputFile);
+ }
+
+ /**
+ * Loads from {@link R.raw raw resources} all the SQL scripts
+ *
+ * @return a List
of String
with the correspondent scripts
+ *
+ * @throws IOException when there is no file available
+ * @see R.raw
+ * @deprecated this method is no longer valid - use {@link #obtainSQLScript()} instead
+ */
+ @Deprecated
+ public List loadSQLScript() throws IOException {
+// FileToBytesExporter exporter = new FileToBytesExporter();
+ List result = new ArrayList<>(5);
+ int[] sqlScripts = new int[]{R.raw.create_category, R.raw.create_entry, R.raw.create_qrcode,
+ R.raw.create_security_code, R.raw.create_field};
+ for (int sqlScript : sqlScripts) {
+ InputStream sqlScriptInputFile = this.mActivityContext.getResources()
+ .openRawResource(sqlScript);
+ StringBuilder builder = new StringBuilder();
+ BufferedReader sqlStringsInFile = new BufferedReader(
+ new InputStreamReader(sqlScriptInputFile));
+ String currentLine;
+ while ((currentLine = sqlStringsInFile.readLine()) != null)
+ builder.append(currentLine).append("\n");
+ result.add(builder.toString());
+ }
+ return result;
+ }
+
+ /**
+ * Loads from {@link R.raw raw resources} the binary SQL script, using {@link
+ * FileToBytesExporter} for recovering data
+ *
+ * @return {@code ArrayList} with the different SQL parts.
+ *
+ * @throws IOException if something happens while recovering the data from the source file.
+ * @see FileToBytesExporter#readObject(File)
+ */
+ public List obtainSQLScript() throws IOException {
+ InputStream sourceFile = mActivityContext
+ .getResources()
+ .openRawResource(R.raw.database_script);
+// FileToBytesExporter reader = new FileToBytesExporter();
+// reader.readObject(sourceFile);
+// String obtainedData = reader.getReadData();
+ StringBuilder data = new StringBuilder();
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(sourceFile))) {
+ String line;
+ while ((line = reader.readLine()) != null)
+ data.append(line).append("\n");
+ }
+ String[] separateScripts = data.toString().split("(\\r?\\n){2}");
+ return new ArrayList<>(Arrays.asList(separateScripts));
+ }
+
+ /**
+ * Loads from {@link R.raw raw resources} the privacy text saved as Markdown file
+ *
+ * @return String
with the hole text
+ *
+ * @throws IOException when there is no file available
+ */
+ public String loadPrivacyTextMD() throws IOException {
+ InputStream privacyPolicyInputStream = this.mActivityContext.getResources()
+ .openRawResource(R.raw.privacy);
+ StringBuilder builder = new StringBuilder();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(privacyPolicyInputStream));
+ String currentLine;
+ while ((currentLine = reader.readLine()) != null)
+ builder.append(currentLine).append("\n");
+ return builder.toString();
+ }
+
+ /**
+ * Loads from {@link R.raw raw resources} the terms and conditions text saved as Markdown
+ * file
+ *
+ * @return String
with the hole text
+ *
+ * @throws IOException when there is no file available
+ */
+ public String loadTermsConditionsTextMD() throws IOException {
+ InputStream termsConditionsStream = this.mActivityContext.getResources()
+ .openRawResource(R.raw.terms_conditions);
+ StringBuilder builder = new StringBuilder();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(termsConditionsStream));
+ String currentLine;
+ while ((currentLine = reader.readLine()) != null)
+ builder.append(currentLine).append("\n");
+ return builder.toString();
+ }
+
+ /**
+ * Obtains the {@code byte[]} value of the user hashed password by applying an encryption
+ * algorithm using RSA - see {@link PasswordCipher} for more information.
+ *
+ * @param userHashedPassword password to encrypt - it must be about 256 bits.
+ *
+ * @return {@code true} when there was no error, {@code false} if something happened.
+ */
+ public boolean savePassword(@NonNull String userHashedPassword) {
+ String alias = Constants.CIPHER.PASSWORD.ALIAS;
+ String filename = Constants.CIPHER.PASSWORD.FILENAME;
+ try {
+ IPasswordCipher cipher = new PasswordCipher(mActivityContext, alias);
+ cipher.createNewKeys();
+ byte[] password = cipher
+ .encryptPassword(userHashedPassword.getBytes(StandardCharsets.UTF_8));
+ File passwordFile = new File(mDataDir.getAbsolutePath() + "/" + filename);
+ if (!passwordFile.exists())
+ passwordFile.createNewFile();
+ try (OutputStream outputStream = new FileOutputStream(passwordFile)) {
+ outputStream.write(Base64.encode(password, Base64.DEFAULT));
+ }
+ return true;
+ } catch (KeyStoreException | InvalidAlgorithmParameterException | InvalidKeyException |
+ UnrecoverableEntryException | IOException ignored) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads, decodes and decrypts a password stored inside the {@linkplain
+ * Constants.CIPHER.PASSWORD password file}.
+ *
+ * @return a {@code byte[]} with the password if the file exists or {@code null} if there was
+ * any error.
+ */
+ public byte[] recoverPassword() {
+ String alias = Constants.CIPHER.PASSWORD.ALIAS;
+ String filename = Constants.CIPHER.PASSWORD.FILENAME;
+ try {
+ IPasswordCipher cipher = new PasswordCipher(mActivityContext, alias);
+ File passwordFile = new File(mDataDir.getAbsolutePath() + "/" + filename);
+ if (!passwordFile.exists())
+ return null;
+ byte[] recoveredPassword = Files.toByteArray(passwordFile);
+ byte[] decodedPassword = Base64.decode(recoveredPassword, Base64.DEFAULT);
+ return cipher.decryptPassword(decodedPassword).getBytes(StandardCharsets.UTF_8);
+ } catch (KeyStoreException | IOException | InvalidKeyException |
+ UnrecoverableEntryException exception) {
+ exception.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Opens and reads the database file that is used by SQLCipher.
+ *
+ * @return {@code byte[]} with the database data, or {@code null} if there is any error.
+ */
+ public byte[] readDatabaseFileAsBytes() {
+ try {
+ return Files.toByteArray(mDatabasePath);
+ } catch (IOException exception) {
+ exception.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Stores a password in {@link com.chamber.java.library.SharedChamber}
+ *
+ * @param userPassword password to save
+ *
+ * @deprecated method as the password is no longer saved in a file
+ */
+ @Deprecated
+ public void storePassword(@NonNull String userPassword) {
+ PasswordSaver passwordSaver = PasswordSaver.instantiate(mActivityContext);
+ passwordSaver.putPassword(userPassword);
+ }
+
+ /**
+ * Reads password from {@link com.chamber.java.library.SharedChamber}
+ *
+ * @return String
with the password
+ *
+ * @deprecated method as the password is no longer saved in a file
+ */
+ @Deprecated
+ @Nullable
+ public String readPassword() {
+ PasswordSaver passwordReader = PasswordSaver.instantiate(mActivityContext);
+ return passwordReader.getPassword();
+ }
+
+ /**
+ * Writes an InputStream with a database backup to an OutputStream
+ *
+ * @param from source
+ *
+ * @deprecated everything is now done at {@link javinator9889.securepass.backup.drive.DriveDownloader
+ * DriveDownloader} class
+ */
+ @Deprecated
+ public void writeDownloadedDatabaseBackup(@NonNull InputStream from) {
+ String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db";
+ try {
+ OutputStream to = new FileOutputStream(filename);
+ IOUtils.copyStream(from, to);
+ } catch (IOException e) {
+ Log.e("Copy IO", "There was an error while trying to copy the InputStream" +
+ " to an OutputStream. Full trace: ", e);
+ }
+ }
+
+ /**
+ * Reads a downloaded database backup from FilesCache
+ *
+ * @return InputStream
when file is available
+ *
+ * @deprecated everything is now done at {@link javinator9889.securepass.backup.drive.DriveDownloader
+ * DriveDownloader} class
+ */
+ @Deprecated
+ public InputStream readDownloadedDatabaseBackup() {
+ String filename = mFilesCache.getAbsolutePath() + "/SecurePass.db";
+ try {
+ return new FileInputStream(filename);
+ } catch (FileNotFoundException e) {
+ Log.e("Read class", "File not found when trying to recover. Full trace: ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Obtains the path where databases backups are saved temporally
+ *
+ * @return String
with the path
+ */
+ public String downloadedDatabaseBackupPath() {
+ return mFilesCache.getAbsolutePath() + "/SecurePass.db";
+ }
+
+ /**
+ * Removes downloaded database backup
+ *
+ * @deprecated everything is now done at {@link javinator9889.securepass.backup.drive.DriveDownloader
+ * DriveDownloader} class
+ */
+ @Deprecated
+ public void deleteDownloadedDatabaseBackup() {
+ String filename = mFilesCache.getAbsolutePath() + "/class.bck";
+
+ File fileToDelete = new File(filename);
+ if (!fileToDelete.delete())
+ Log.e("Delete IO", "There was an error while trying to delete class.bck");
+ }
+
+ /**
+ * Obtains the path where database is stored
+ *
+ * @return File
with the path
+ */
+ public File getDatabasePath() {
+ return mDatabasePath;
+ }
+}
diff --git a/APP/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java
similarity index 78%
rename from APP/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java
rename to SecurePass/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java
index 1af75c4..799d15a 100644
--- a/APP/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/DatabaseManager.java
@@ -1,162 +1,179 @@
-package javinator9889.securepass.io.database;
-
-import android.content.Context;
-import android.util.Log;
-
-import net.sqlcipher.database.SQLiteDatabase;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import javinator9889.securepass.io.IOManager;
-import javinator9889.securepass.io.database.operations.CommonOperations;
-import javinator9889.securepass.util.resources.ISharedPreferencesManager;
-import javinator9889.securepass.util.resources.PreferencesManager;
-import javinator9889.securepass.util.values.Constants;
-
-/**
- * Created by Javinator9889 on 26/03/2018.
- * Based on SQLCipher documentation
- */
-
-public class DatabaseManager {
- private Context mActivityContext;
- private File mDatabaseFile;
- private String mUserHashedPassword;
- private Thread mDatabaseInitializer;
-
- /**
- * Generates a new instance and also initializes the database with {@link #initDB()} method
- *
- * @param activityContext Context
when instantiating the class
- * @param userHashedPassword password for encrypting/decrypting the database
- * @see Context
- * @see #initDB()
- */
- private DatabaseManager(Context activityContext, @NonNull String userHashedPassword) {
- this.mActivityContext = activityContext;
- this.mUserHashedPassword = userHashedPassword;
- initDB();
- }
-
- /**
- * Generates a DatabaseManager
instance
- *
- * @param activityContext Context
when instantiating the class
- * @param userHashedPassword password for encrypting/decrypting the database
- * @return DatabaseManager
instance
- * @see Context
- */
- @NonNull
- public static DatabaseManager newInstance(Context activityContext,
- @NonNull String userHashedPassword) {
- return new DatabaseManager(activityContext, userHashedPassword);
- }
-
- /**
- * Initializes de database with the required script on a separate thread.
- *
- * It reads from {@link ISharedPreferencesManager} if the
- * {@link ISharedPreferencesManager#isApplicationInitialized() application is initialized
- * } for creating the correspondent files.
- * If the
- * {@link ISharedPreferencesManager#isDatabaseInitialized() database is initialized} it
- * will not load again the scripts. Else, by using {@link IOManager} it will create the
- * tables inside SQLite
- *
- *
- * @see SQLiteDatabase
- * @see PreferencesManager
- * @see IOManager#loadSQLScript()
- */
- private void initDB() {
- mDatabaseInitializer = new Thread(new Runnable() {
- private final Context databaseContext = DatabaseManager.this.mActivityContext;
- private final String databasePassword = DatabaseManager.this.mUserHashedPassword;
-
- @Override
- public void run() {
- SQLiteDatabase.loadLibs(databaseContext);
- ISharedPreferencesManager preferencesManager = PreferencesManager.getInstance();
- mDatabaseFile = databaseContext
- .getDatabasePath(Constants.SQL.DB_FILENAME);
- if (!preferencesManager.isApplicationInitialized()) {
- try {
- mDatabaseFile.delete();
- mDatabaseFile.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
- mDatabaseFile,
- databasePassword,
- null);
- List databaseScripts;
- try {
- if (!preferencesManager.isDatabaseInitialized()) {
- databaseScripts = IOManager.newInstance(databaseContext).loadSQLScript();
- for (String script : databaseScripts) {
- database.execSQL(script);
- }
- DatabaseManager.this.createDefaultCategory();
- }
- } catch (IOException e) {
- throw new RuntimeException(e.getCause());
- } finally {
- database.close();
- }
- }
- });
- mDatabaseInitializer.setName(Constants.SQL.DB_INIT_THREAD_NAME);
- mDatabaseInitializer.setUncaughtExceptionHandler(new ThreadExceptionHandler());
- mDatabaseInitializer.run();
- }
-
- /**
- * Gets the database instance from SQLite
- *
- * @return SQLiteDatabase
instance
- */
- public SQLiteDatabase getDatabaseInstance() {
- SQLiteDatabase.loadLibs(mActivityContext);
- return SQLiteDatabase.openOrCreateDatabase(mDatabaseFile, mUserHashedPassword, null);
- }
-
- /**
- * Gets the thread when running for joining the database initializer with current thread
- *
- * @return Thread
with the init process
- * @see Thread
- * @see Thread#join()
- */
- public Thread getDatabaseInitializer() {
- return mDatabaseInitializer;
- }
-
- /**
- * Creates the default category necessary in order to allow the hole application work
- */
- private void createDefaultCategory() {
- CommonOperations operations = CommonOperations.newInstance(this);
- operations.registerDefaultCategory();
- operations.finishConnection();
- }
-
- /**
- * Class for handling Threading
exceptions
- */
- private class ThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
- /**
- * {@inheritDoc}
- */
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- Log.e(t.getName(), "Exception in thread \"" + t.getName() + "\" with " +
- "exception thrown -> " + e.getMessage() + "\nFull trace: ");
- e.printStackTrace();
- }
- }
-}
+package javinator9889.securepass.io.database;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.github.javinator9889.exporter.FileToBytesExporter;
+
+import net.sqlcipher.database.SQLiteDatabase;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.io.IOManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.util.resources.ISharedPreferencesManager;
+import javinator9889.securepass.util.resources.PreferencesManager;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Created by Javinator9889 on 26/03/2018.
+ * Based on SQLCipher documentation
+ */
+
+public class DatabaseManager {
+ private static DatabaseManager INSTANCE = null;
+ // private Context mActivityContext;
+ private File mDatabaseFile;
+ private String mUserHashedPassword;
+ private Thread mDatabaseInitializer;
+
+ /**
+ * Generates a new instance and also initializes the database with {@link #initDB(Context)} method
+ *
+ * @param activityContext Context
when instantiating the class
+ * @param userHashedPassword password for encrypting/decrypting the database
+ * @see Context
+ * @see #initDB(Context)
+ */
+ private DatabaseManager(Context activityContext, @NonNull String userHashedPassword) {
+// this.mActivityContext = activityContext;
+ this.mUserHashedPassword = userHashedPassword;
+ initDB(activityContext);
+ INSTANCE = this;
+ }
+
+ /**
+ * Generates a DatabaseManager
instance. If the libraries are loaded
+ *
+ * @param activityContext Context
when instantiating the class
+ * @param userHashedPassword password for encrypting/decrypting the database
+ * @return DatabaseManager
instance
+ * @see Context
+ */
+ @NonNull
+ public static DatabaseManager getInstance(Context activityContext,
+ @NonNull String userHashedPassword) {
+ return INSTANCE == null ?
+ new DatabaseManager(activityContext, userHashedPassword) :
+ INSTANCE;
+ }
+
+ /**
+ * Initializes de database with the required script on a separate thread.
+ *
+ * It reads from {@link ISharedPreferencesManager} if the
+ * {@link ISharedPreferencesManager#isApplicationInitialized() application is initialized
+ * } for creating the correspondent files.
+ * If the
+ * {@link ISharedPreferencesManager#isDatabaseInitialized() database is initialized} it
+ * will not load again the scripts. Else, by using {@link IOManager} it will create the
+ * tables inside SQLite
+ *
+ *
+ * @param databaseContext Context
when instantiating the class
+ * @see SQLiteDatabase
+ * @see PreferencesManager
+ * @see IOManager#loadSQLScript()
+ */
+ private void initDB(@NonNull final Context databaseContext) {
+ mDatabaseInitializer = new Thread(new Runnable() {
+ // private final Context databaseContext = DatabaseManager.this.mActivityContext;
+ private final String databasePassword = DatabaseManager.this.mUserHashedPassword;
+
+ @Override
+ public void run() {
+ SQLiteDatabase.loadLibs(databaseContext);
+ ISharedPreferencesManager preferencesManager = PreferencesManager.getInstance();
+ mDatabaseFile = databaseContext
+ .getDatabasePath(Constants.SQL.DB_FILENAME);
+ if (!preferencesManager.isApplicationInitialized()) {
+ try {
+ mDatabaseFile.delete();
+ mDatabaseFile.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
+ mDatabaseFile,
+ databasePassword,
+ null);
+ List databaseScripts;
+ try {
+ if (!preferencesManager.isDatabaseInitialized()) {
+ databaseScripts = IOManager.newInstance(databaseContext).obtainSQLScript();
+ for (String script : databaseScripts) {
+ database.execSQL(script);
+ }
+ DatabaseManager.this.createDefaultCategory();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e.getCause());
+ } finally {
+ database.close();
+ }
+ }
+ });
+ mDatabaseInitializer.setName(Constants.SQL.DB_INIT_THREAD_NAME);
+ mDatabaseInitializer.setUncaughtExceptionHandler(new ThreadExceptionHandler());
+ mDatabaseInitializer.run();
+ }
+
+ /**
+ * Gets the database instance from SQLite
+ *
+ * @return SQLiteDatabase
instance
+ */
+ public SQLiteDatabase getDatabaseInstance() {
+// SQLiteDatabase.loadLibs(context);
+ return SQLiteDatabase.openOrCreateDatabase(mDatabaseFile, mUserHashedPassword, null);
+ }
+
+ /**
+ * Gets the thread when running for joining the database initializer with current thread
+ *
+ * @return Thread
with the init process
+ * @see Thread
+ * @see Thread#join()
+ */
+ public Thread getDatabaseInitializer() {
+ return mDatabaseInitializer;
+ }
+
+ /**
+ * Finalizes this instance (e.g.: the ongoing database operations are finished) - method should
+ * be called whether is going to use a new instance.
+ */
+ public static void finish() {
+ INSTANCE = null;
+ }
+
+ /**
+ * Creates the default category necessary in order to allow the hole application work
+ */
+ private void createDefaultCategory() {
+ CommonOperations operations = new CommonOperations(this);
+ operations.registerDefaultCategory();
+ operations.finishConnection();
+ }
+
+ /**
+ * Class for handling Threading
exceptions
+ */
+ private class ThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ Log.e(t.getName(), "Exception in thread \"" + t.getName() + "\" with " +
+ "exception thrown -> " + e.getMessage() + "\nFull trace: ");
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java
new file mode 100644
index 0000000..2280834
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/CommonOperations.java
@@ -0,0 +1,491 @@
+package javinator9889.securepass.io.database.operations;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import com.github.javinator9889.exporter.FileToBytesExporter;
+import com.github.javinator9889.threading.pools.ThreadsPooling;
+import com.github.javinator9889.threading.threads.notifyingthread.NotifyingThread;
+import com.github.javinator9889.threading.threads.notifyingthread.OnThreadCompletedListener;
+
+import net.sqlcipher.Cursor;
+import net.sqlcipher.database.SQLiteDatabase;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import java8.util.J8Arrays;
+import javinator9889.securepass.errors.database.ExecutorNonDefinedException;
+import javinator9889.securepass.errors.database.NoJobsEnqueuedError;
+import javinator9889.securepass.errors.database.OverriddenMethodsNotDefinedError;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants.SQL;
+
+/**
+ * Created by Javinator9889 on 29/03/2018.
+ */
+public class CommonOperations implements OnThreadCompletedListener {
+ private static final String TAG = "Database Operations";
+ private static final String WHERE_ID = null;
+ private static final String TABLE_NAME = null;
+ private SQLiteDatabase mDatabase;
+ private ThreadsPooling mExecutor;
+ private ObjectContainer mWaitingThreads;
+
+ /**
+ * Public constructor for creating this class - use this instead of {@link
+ * #newInstance(DatabaseManager)}.
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object.
+ * @see DatabaseManager
+ */
+ public CommonOperations(@NonNull DatabaseManager databaseInstance) {
+ try {
+ if (databaseInstance.getDatabaseInitializer().isAlive())
+ databaseInstance.getDatabaseInitializer().join();
+ mDatabase = databaseInstance.getDatabaseInstance();
+ mExecutor = ThreadsPooling.builder().build();
+ mWaitingThreads = new ObjectContainer<>();
+ } catch (InterruptedException e) {
+ Log.e(getTag(), "Error while trying to join thread \""
+ + SQL.DB_INIT_THREAD_NAME + "\". Interrupted exception. Full trace:", e);
+ }
+ }
+
+ /**
+ * Public class loader - uses {@link #CommonOperations(DatabaseManager) private constructor}
+ *
+ * @param databaseManagerInstance instance of the {@link DatabaseManager} object
+ * @return CommonOperations
+ * @deprecated use {@link #CommonOperations(DatabaseManager)} instead
+ */
+ @Deprecated
+ public static CommonOperations newInstance(DatabaseManager databaseManagerInstance) {
+ return new CommonOperations(databaseManagerInstance);
+ }
+
+ /**
+ * Whenever {@link SQLiteDatabase#needUpgrade(int)} is called (and the result is {@code
+ * true}), this method should be called as it will upgrade the database.
+ *
+ * @param source the new database version that will be updated.
+ * @throws IOException whenever the source does not exists or there is any error while
+ * reading (for example, it has been closed).
+ */
+ public void onDatabaseUpdate(@NonNull InputStream source) throws IOException {
+ FileToBytesExporter opener = new FileToBytesExporter();
+ opener.readObject(source);
+ String[] newDatabaseVersion = opener.getReadData().split("(\\r?\\n){2}");
+ for (String query : newDatabaseVersion)
+ mDatabase.execSQL(query);
+ }
+
+ /**
+ * Method for changing the database password
+ *
+ * @param newDatabasePassword new password
+ * @see SQLiteDatabase#changePassword(String)
+ */
+ public void changeDatabasePassword(@NonNull String newDatabasePassword) {
+ this.mDatabase.changePassword(newDatabasePassword);
+ }
+
+ /**
+ * Registers the default ("Global") category
+ *
+ * @return long
with the category ID (should be '1')
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ */
+ public long registerDefaultCategory() {
+ ContentValues params = new ContentValues();
+ params.put(SQL.CATEGORY.C_ID, 0);
+ params.put(SQL.CATEGORY.C_NAME, "Global");
+ return mDatabase.insertWithOnConflict(SQL.CATEGORY.NAME, null, params,
+ SQLiteDatabase.CONFLICT_IGNORE);
+ }
+
+ /**
+ * Gets the tag for {@link android.util.Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ public String getWhereId() {
+ return WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Tries to insert the data at the specified table
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error occurred
+ * @see SQLiteDatabase#insert(String, String, ContentValues)
+ * @see ContentValues
+ */
+ protected long insert(@NonNull String tableName, @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insert(tableName, null, params);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Tries to insert the data at the specified table ignoring conflicts
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error occurred
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ * @see SQLiteDatabase#CONFLICT_IGNORE
+ * @see ContentValues
+ */
+ protected long insertIgnoreOnConflict(@NonNull String tableName,
+ @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase
+ .CONFLICT_IGNORE);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Tries to insert the data at the specified table aborting when conflicts occur
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error occurred
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ * @see SQLiteDatabase#CONFLICT_ABORT
+ * @see ContentValues
+ */
+ protected long insertAbortOnConflict(@NonNull String tableName, @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase
+ .CONFLICT_ABORT);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Tries to insert the data at the specified table doing nothing with conflicts
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error ocurred
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ * @see SQLiteDatabase#CONFLICT_NONE
+ * @see ContentValues
+ */
+ protected long insertNoneOnConflit(@NonNull String tableName, @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase
+ .CONFLICT_NONE);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Tries to insert the data at the specified table failing with conflicts
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error occurred
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ * @see SQLiteDatabase#CONFLICT_FAIL
+ * @see ContentValues
+ */
+ protected long insertFailOnConflict(@NonNull String tableName, @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase
+ .CONFLICT_FAIL);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ else
+ throw new RuntimeException("Error occurred while inserting data");
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Tries to insert the data at the specified table replacing conflicts
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error occurred
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ * @see SQLiteDatabase#CONFLICT_REPLACE
+ * @see ContentValues
+ */
+ protected long insertReplaceOnConflict(@NonNull String tableName,
+ @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase
+ .CONFLICT_REPLACE);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Tries to insert the data at the specified table rolling back on conflicts
+ *
+ * @param tableName the table to insert the row
+ * @param params map containing the initial values
+ * @return the row ID or -1 if any error occurred
+ * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
+ * @see SQLiteDatabase#CONFLICT_ROLLBACK
+ * @see ContentValues
+ */
+ protected long insertRollbackOnConflict(@NonNull String tableName,
+ @NonNull ContentValues params) {
+ mDatabase.beginTransaction();
+ long insertResult = mDatabase.insertWithOnConflict(tableName, null, params, SQLiteDatabase
+ .CONFLICT_ROLLBACK);
+ if (insertResult != -1)
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ return insertResult;
+ }
+
+ /**
+ * Updates table information if exists
+ *
+ * @param tableName table name to modify
+ * @param values new values to insert
+ * @param whereClause SQL where clause
+ * @param whereArgs SQL where args (probably it is an ID)
+ * @return the affected rows
+ * @throws net.sqlcipher.SQLException If the SQL string is invalid for some reason
+ * @throws IllegalStateException if the database is not open
+ */
+ protected int update(@NonNull String tableName,
+ @NonNull ContentValues values,
+ @NonNull String whereClause,
+ @NonNull String[] whereArgs) {
+ return mDatabase.update(tableName, values, whereClause, whereArgs);
+ }
+
+ /**
+ * Obtains the specified table information and saves it inside a {@link Cursor}
+ *
+ * @param tableName where to obtain the values.
+ * @param columnsToGet which columns to get - passing null will return all columns.
+ * @param whereClause where to obtain data - passing null will return all rows.
+ * @param args args for modifying the whereClause statement.
+ * @param groupBy a filter declaring how to group rows - passing null will cause the rows
+ * to not to be grouped.
+ * @param having a filter declaring which row groups to include in the cursor, if groupBy
+ * is being used
+ * @param orderBy how to order the rows - passing null will use the default sort order
+ * @return a {@link Cursor} object positioned before the first entry
+ * @throws net.sqlcipher.SQLException if there is an issue executing the SQL
+ * @throws IllegalStateException if the database is not open
+ * @see Cursor
+ */
+ protected Cursor get(@NonNull String tableName,
+ @Nullable String[] columnsToGet,
+ @Nullable String whereClause,
+ @Nullable String[] args,
+ @Nullable String groupBy,
+ @Nullable String having,
+ @Nullable String orderBy) {
+ return mDatabase
+ .query(tableName, columnsToGet, whereClause, args, groupBy, having, orderBy);
+ }
+
+ /**
+ * Gets all fields for the given table name
+ *
+ * @param tableName where to obtain the values
+ * @return a {@link Cursor} object positioned before the first entry
+ * @throws net.sqlcipher.SQLException if there is an issue executing the SQL
+ * @throws IllegalStateException if the database is not open
+ * @see Cursor
+ */
+ protected Cursor getAll(@NonNull String tableName, @Nullable String orderBy) {
+ return get(tableName, null, null, null, null, null, orderBy);
+ }
+
+ /**
+ * Generates a {@link Map} of the values obtained by the cursor, assigning the {@code column
+ * name} to its index - useful for retrieving values from {@code SELECT} clause.
+ *
+ * @param cursor the source cursor from which the values will be obtained.
+ * @return {@code Map} with the relation between column name and column index.
+ * @see HashMap
+ */
+ @NonNull
+ protected Map constructMapFromCursor(@NonNull Cursor cursor) {
+ String[] columnNames = cursor.getColumnNames();
+ Map result = new HashMap<>(cursor.getColumnCount(), 1.0f);
+ for (String columnName : columnNames) {
+ int index = cursor.getColumnIndex(columnName);
+ result.put(columnName, index);
+ }
+ return result;
+ }
+
+ /**
+ * Deletes all columns for a given ID of a table
+ *
+ * @param tableName table to delete values
+ * @param idFieldName table column name which contains the ID
+ * @param id ID of the row to delete
+ * @return the number of rows affected
+ * @throws net.sqlcipher.SQLException If the SQL string is invalid for some reason
+ * @throws IllegalStateException if the database is not open
+ */
+ protected int delete(@NonNull String tableName, @NonNull String idFieldName, long id) {
+ String whereClause = idFieldName + "=?";
+ return mDatabase.delete(tableName, whereClause, setSelectionArgs(id));
+ }
+
+ /**
+ * Closes database connection.
+ *
+ * @see SQLiteDatabase#close()
+ */
+ public void finishConnection() {
+ try {
+ mExecutor.shutdownWaitTermination();
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Task executor was interrupted while waiting threads to finish", e);
+ } finally {
+ mDatabase.close();
+ DatabaseManager.finish();
+ }
+ }
+
+ /**
+ * Casts {@code long} to a {@code String[]} array
+ *
+ * @param id ID to cast
+ * @return {@code String[]} with the ID value
+ */
+ private String[] setSelectionArgs(long id) {
+ return new String[]{String.valueOf(id)};
+ }
+
+ /**
+ * Converts an array of {@code Object} varargs into a {@code String} array
+ *
+ * @param args amount of elements to store in a {@code String} array
+ * @return {@code String[]} containing the args
+ */
+ protected String[] whereArgs(@NonNull Object... args) {
+ return J8Arrays.stream(args).map(Object::toString).toArray(String[]::new);
+// return Arrays.copyOf(args, args.length, String[].class);
+ }
+
+ /**
+ * Schedules an update operation by using the given ID and new values
+ *
+ * @param id ID where changing values
+ * @param params new values
+ * @throws OverriddenMethodsNotDefinedError when {@link #getTableName()} or {@link
+ * #getWhereId()} are not overridden.
+ * @throws ExecutorNonDefinedException if, for any reason, executor is {@code null}.
+ * @see ThreadsPooling#add(Runnable)
+ * @see ThreadsPooling#start()
+ */
+ protected void scheduleUpdateExecutor(long id, @NonNull ContentValues params) {
+ if (getTableName() == null || getWhereId() == null) {
+ StringBuilder nonDefinedAttributes = new StringBuilder(3);
+ boolean isFirstDefined = false;
+ if (getTableName() == null) {
+ nonDefinedAttributes.append("getTableName()");
+ isFirstDefined = true;
+ }
+ if (getWhereId() == null)
+ if (isFirstDefined)
+ nonDefinedAttributes.append(", ");
+ nonDefinedAttributes.append("getWhereId()");
+ throw new OverriddenMethodsNotDefinedError("Following methods not overridden: " +
+ nonDefinedAttributes.toString());
+ }
+ if (mExecutor == null)
+ throw new ExecutorNonDefinedException("You must define the \"ThreadsPooling\" by " +
+ "using \"CommonOperations(DatabaseManager)\" constructor");
+ BlockingQueue queue = mExecutor.getWorkingThreadsQueue();
+ if (queue.remainingCapacity() == 0)
+ mWaitingThreads.storeObject(() -> update(getTableName(), params, getWhereId(),
+ whereArgs(id)));
+ else
+ mExecutor.add(new NotifyingThread(() -> update(getTableName(), params, getWhereId(),
+ whereArgs(id)), this));
+ }
+
+ /**
+ * Runs the {@link ThreadsPooling} - only necessary when doing UPDATE operations
+ *
+ * @throws NoJobsEnqueuedError when there is no job added to the queue
+ */
+ public void apply() {
+ int startedThreads = mExecutor.start();
+ if (startedThreads == 0)
+ throw new NoJobsEnqueuedError("There is no pending thread waiting to be executed");
+ }
+
+ /**
+ * When a thread finish its execution, if using a {@link NotifyingThread} and the class is
+ * subscribed, this method is called, with the {@code Runnable} which corresponds the just
+ * finished thread, and the {@code Throwable} containing the exception (if any exception has
+ * benn thrown).
+ *
+ * Refer to {@link NotifyingThread#addOnThreadCompletedListener(OnThreadCompletedListener)} for
+ * getting more information about subscribing classes.
+ *
+ * @param thread the thread that has just finished its execution.
+ * @param exception the exception if happened, else {@code null}.
+ */
+ @Override
+ public void onThreadCompletedListener(@NotNull Thread thread,
+ @org.jetbrains.annotations.Nullable Throwable exception) {
+ if (mWaitingThreads.isAnyObjectStored()) {
+ Runnable firstObject = mWaitingThreads.getStoredObjectAtIndex(0);
+ if (firstObject != null) {
+ mExecutor.add(firstObject);
+ mWaitingThreads.removeObjectAtIndex(0);
+ }
+ }
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/CategoryOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/CategoryOperations.java
new file mode 100644
index 0000000..ceefc69
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/CategoryOperations.java
@@ -0,0 +1,180 @@
+package javinator9889.securepass.io.database.operations.category;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.data.entry.Category;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants.SQL.CATEGORY;
+import javinator9889.securepass.util.values.database.CategoryFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 31/10/2018 - APP.
+ */
+public class CategoryOperations extends CommonOperations implements ICategorySetOperations,
+ ICategoryGetOperations {
+ private static final String TAG = "Category Operations";
+ private static final String TABLE_NAME = CATEGORY.NAME;
+ private static final CategoryFields ID = CategoryFields.ID;
+ private static final CategoryFields NAME = CategoryFields.NAME;
+ private static final String CATEGORY_WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseManager instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public CategoryOperations(@NonNull DatabaseManager databaseManager) {
+ super(databaseManager);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @NonNull
+ @Override
+ public String getWhereId() {
+ return CATEGORY_WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @NonNull
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains the category name by using the given ID
+ *
+ * @param categoryId the category ID where obtaining the name
+ *
+ * @return {@code String} with the name
+ */
+ @Override
+ public String getCategoryName(long categoryId) {
+ String name = null;
+ try (Cursor categoryCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()),
+ CATEGORY_WHERE_ID, whereArgs(categoryId), null, null, ID.getFieldName() + " ASC")) {
+ Map categoriesColumns = constructMapFromCursor(categoryCursor);
+ if (categoryCursor.moveToNext())
+ name = categoryCursor.getString(categoriesColumns.get(NAME.getFieldName()));
+ }
+ return name;
+ }
+
+ /**
+ * Obtains all categories' data and saves it inside a {@link GeneralObjectContainer} of {@link
+ * Category}
+ *
+ * @return {@code GeneralObjectContainer} of categories
+ *
+ * @see ObjectContainer
+ * @see Category
+ */
+ @Override
+ public GeneralObjectContainer getAllCategories() {
+ GeneralObjectContainer categories = new ObjectContainer<>();
+ try (Cursor categoriesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map categoriesColumns = constructMapFromCursor(categoriesCursor);
+ while (categoriesCursor.moveToNext()) {
+ long id = categoriesCursor.getLong(categoriesColumns.get(ID.getFieldName()));
+ String name = categoriesCursor.getString(categoriesColumns.get(NAME.getFieldName()));
+ Category currentCategory = new Category(id, name);
+ categories.storeObject(currentCategory);
+ }
+ }
+ return categories;
+ }
+
+ /**
+ * Registers a new simple category
+ *
+ * @param categoryName the name of the new category
+ *
+ * @return {@code long} with the new category ID
+ */
+ @Override
+ public long registerNewCategory(@NonNull String categoryName) {
+ ContentValues params = setParams(categoryName);
+ return insertFailOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates the category name by using the given ID
+ *
+ * @param categoryId id of the category to update
+ * @param categoryName new name
+ */
+ @Override
+ public void updateCategoryName(long categoryId, @NonNull String categoryName) {
+ ContentValues params = setParams(categoryName);
+ scheduleUpdateExecutor(categoryId, params);
+ }
+
+ /**
+ * Removes the hole category by the given ID
+ *
+ * @param categoryId category ID to remove
+ */
+ @Override
+ public void removeCategory(long categoryId) {
+ int i = delete(TABLE_NAME, ID.getFieldName(), categoryId);
+ Log.d(TAG, "Number of rows deleted: " + i);
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param categoryName category name
+ *
+ * @return {@code ContentValues} with the params
+ */
+ private ContentValues setParams(@NonNull String categoryName) {
+ ContentValues params = new ContentValues(1);
+ params.put(NAME.getFieldName(), categoryName);
+ return params;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategoryGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategoryGetOperations.java
new file mode 100644
index 0000000..48c82ca
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategoryGetOperations.java
@@ -0,0 +1,42 @@
+package javinator9889.securepass.io.database.operations.category;
+
+import javinator9889.securepass.data.entry.Category;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 31/10/2018 - APP.
+ */
+public interface ICategoryGetOperations {
+ /**
+ * Obtains the category name by using the given ID
+ *
+ * @param categoryId the category ID where obtaining the name
+ * @return {@code String} with the name
+ */
+ String getCategoryName(long categoryId);
+
+ /**
+ * Obtains all categories' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link Category}
+ *
+ * @return {@code GeneralObjectContainer} of categories
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see Category
+ */
+ GeneralObjectContainer getAllCategories();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategorySetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategorySetOperations.java
new file mode 100644
index 0000000..10b73c0
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/category/ICategorySetOperations.java
@@ -0,0 +1,51 @@
+package javinator9889.securepass.io.database.operations.category;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 31/10/2018 - APP.
+ */
+public interface ICategorySetOperations {
+ /**
+ * Registers a new simple category
+ *
+ * @param categoryName the name of the new category
+ * @return {@code long} with the new category ID
+ */
+ long registerNewCategory(@NonNull String categoryName);
+
+ /**
+ * Updates the category name by using the given ID
+ *
+ * @param categoryId id of the category to update
+ * @param categoryName new name
+ */
+ void updateCategoryName(long categoryId, @NonNull String categoryName);
+
+ /**
+ * Removes the hole category by the given ID
+ *
+ * @param categoryId category ID to remove
+ */
+ void removeCategory(long categoryId);
+
+ /**
+ * Applies pending changes to the database - only necessary when doing UPDATE operations
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/ConfigurationOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/ConfigurationOperations.java
new file mode 100644
index 0000000..776dae1
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/ConfigurationOperations.java
@@ -0,0 +1,183 @@
+package javinator9889.securepass.io.database.operations.configuration;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.Configuration;
+import javinator9889.securepass.data.configuration.IConfiguration;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.database.ConfigurationFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class ConfigurationOperations extends CommonOperations
+ implements IConfigurationSetOperations, IConfigurationGetOperations {
+ private static final String TAG = "Configuration Operations";
+ private static final String TABLE_NAME = Constants.SQL.CONFIGURATION.NAME;
+ private static final ConfigurationFields ID = ConfigurationFields.ID;
+ private static final ConfigurationFields NAME = ConfigurationFields.NAME;
+ private static final String WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public ConfigurationOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getWhereId() {
+ return WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains the configuration's name by using its ID
+ *
+ * @param configurationId ID of the configuration
+ *
+ * @return {@code String} with the configuration name
+ */
+ @Override
+ public String getConfigurationName(long configurationId) {
+ String name = null;
+ try (Cursor configurationCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()),
+ WHERE_ID, whereArgs(configurationId), null, null, ID.getFieldName() + " ASC")) {
+ Map configurationsColumns = constructMapFromCursor(configurationCursor);
+ if (configurationCursor.moveToNext())
+ name = configurationCursor.getString(configurationsColumns.get(NAME.getFieldName()));
+ }
+ return name;
+ }
+
+ /**
+ * Obtains all configurations' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfiguration}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see Configuration
+ */
+ @Override
+ public GeneralObjectContainer getAllConfigurations() {
+ GeneralObjectContainer configurations = new ObjectContainer<>();
+ try (Cursor configurationsCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map configColumns = constructMapFromCursor(configurationsCursor);
+ while (configurationsCursor.moveToNext()) {
+ long id = configurationsCursor.getLong(configColumns.get(ID.getFieldName()));
+ String name = configurationsCursor.getString(configColumns.get(NAME.getFieldName()));
+ IConfiguration currentConfiguration = new Configuration(id, name, null);
+ configurations.storeObject(currentConfiguration);
+ }
+ }
+ return configurations;
+ }
+
+ /**
+ * Registers a new simple configuration
+ *
+ * @param configurationName new custom configuration name
+ *
+ * @return {@code long} with the new configuration ID
+ */
+ @Override
+ public long registerNewConfiguration(@NonNull String configurationName) {
+ ContentValues params = setParams(configurationName);
+ return insertReplaceOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates the configuration's name by using its ID
+ *
+ * @param configurationId ID of the configuration
+ * @param configurationName new configuration name
+ */
+ @Override
+ public void updateConfigurationName(long configurationId, @NonNull String configurationName) {
+ ContentValues params = setParams(configurationName);
+ scheduleUpdateExecutor(configurationId, params);
+ }
+
+ /**
+ * Removes the configuration from the DB
+ *
+ * @param configurationId ID of the configuration to delete
+ */
+ @Override
+ public void removeConfiguration(long configurationId) {
+ delete(TABLE_NAME, ID.getFieldName(), configurationId);
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param name configuration name
+ *
+ * @return {@code ContentValues} with the params
+ *
+ * @see ContentValues
+ */
+ private ContentValues setParams(@NonNull String name) {
+ ContentValues params = new ContentValues(1);
+ params.put(NAME.getFieldName(), name);
+ return params;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationGetOperations.java
new file mode 100644
index 0000000..843bcc8
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationGetOperations.java
@@ -0,0 +1,44 @@
+package javinator9889.securepass.io.database.operations.configuration;
+
+import javinator9889.securepass.data.configuration.Configuration;
+import javinator9889.securepass.data.configuration.IConfiguration;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface IConfigurationGetOperations {
+ /**
+ * Obtains the configuration's name by using its ID
+ *
+ * @param configurationId ID of the configuration
+ * @return {@code String} with the configuration name
+ */
+ String getConfigurationName(long configurationId);
+
+ /**
+ * Obtains all configurations' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link javinator9889.securepass.data.configuration.IConfiguration}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see ObjectContainer
+ * @see Configuration
+ */
+ GeneralObjectContainer getAllConfigurations();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationSetOperations.java
new file mode 100644
index 0000000..fe0128a
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/IConfigurationSetOperations.java
@@ -0,0 +1,54 @@
+package javinator9889.securepass.io.database.operations.configuration;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.errors.database.NoJobsEnqueuedError;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface IConfigurationSetOperations {
+ /**
+ * Registers a new simple configuration
+ *
+ * @param configurationName new custom configuration name
+ *
+ * @return {@code long} with the new configuration ID
+ */
+ long registerNewConfiguration(@NonNull String configurationName);
+
+ /**
+ * Updates the configuration's name by using its ID
+ *
+ * @param configurationId ID of the configuration
+ * @param configurationName new configuration name
+ */
+ void updateConfigurationName(long configurationId, @NonNull String configurationName);
+
+ /**
+ * Removes the configuration from the DB
+ *
+ * @param configurationId ID of the configuration to delete
+ */
+ void removeConfiguration(long configurationId);
+
+ /**
+ * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary
+ * when doing UPDATE operations
+ *
+ * @throws NoJobsEnqueuedError when there is no job added to the queue
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/ConfigFieldsOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/ConfigFieldsOperations.java
new file mode 100644
index 0000000..60ad91c
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/ConfigFieldsOperations.java
@@ -0,0 +1,221 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.ConfigFields;
+import javinator9889.securepass.data.configuration.IConfigFields;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.database.ConfigFieldsFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public abstract class ConfigFieldsOperations extends CommonOperations
+ implements IConfigFieldsSetOperations, IConfigFieldsGetOperations {
+ protected static final ConfigFieldsFields ID = ConfigFieldsFields.ID;
+ protected static final ConfigFieldsFields DESCRIPTION = ConfigFieldsFields.DESCRIPTION;
+ protected static final ConfigFieldsFields ORDER = ConfigFieldsFields.ORDER;
+ protected static final ConfigFieldsFields CONFIGURATION = ConfigFieldsFields.CONFIGURATION;
+ protected static final String ORDER_BY = ID.getFieldName() + " ASC";
+ private static final String WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ protected ConfigFieldsOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Obtains the current description for the field
+ *
+ * @param id ID of the field where obtaining the data
+ *
+ * @return {@code String} with the name
+ */
+ @Override
+ public String getConfigFieldDescription(long id) {
+ String description = null;
+ try (Cursor configFieldsCursor = get(getTableName(), whereArgs(DESCRIPTION.getFieldName()),
+ getWhereId(), whereArgs(id), null, null, ORDER_BY)) {
+ Map configurationsColumns = constructMapFromCursor(configFieldsCursor);
+ if (configFieldsCursor.moveToNext())
+ description = configFieldsCursor.getString(configurationsColumns.get(DESCRIPTION.getFieldName()));
+ }
+ return description;
+ }
+
+ /**
+ * Obtains the current field's order
+ *
+ * @param id ID of the field where obtaining the data
+ *
+ * @return {@code int} with the ordinal order
+ */
+ @Override
+ public int getConfigFieldOrder(long id) {
+ int order = -1;
+ try (Cursor configFieldsCursor = get(getTableName(), whereArgs(ORDER.getFieldName()),
+ getWhereId(), whereArgs(id), null, null, ORDER_BY)) {
+ Map configurationsColumns = constructMapFromCursor(configFieldsCursor);
+ if (configFieldsCursor.moveToNext())
+ order = configFieldsCursor.getInt(configurationsColumns.get(ORDER.getFieldName()));
+ }
+ return order;
+ }
+
+ /**
+ * Obtains the current field's parent ID
+ *
+ * @param id ID of the field where obtaining the data
+ *
+ * @return {@code long} with the ID
+ */
+ @Override
+ public long getConfigFieldConfigurationId(long id) {
+ long configurationId = -1;
+ try (Cursor configFieldsCursor = get(getTableName(), whereArgs(CONFIGURATION.getFieldName()),
+ getWhereId(), whereArgs(id), null, null, ORDER_BY)) {
+ Map configurationsColumns = constructMapFromCursor(configFieldsCursor);
+ if (configFieldsCursor.moveToNext())
+ configurationId = configFieldsCursor.getLong(configurationsColumns.get
+ (CONFIGURATION.getFieldName()));
+ }
+ return configurationId;
+ }
+
+
+ /**
+ * Registers a new simple configuration field
+ *
+ * @param description field description
+ * @param order field order for displaying at UI
+ * @param configurationId parent configuration ID
+ *
+ * @return {@code long} with the new ID
+ */
+ @Override
+ public long registerNewConfigField(@NonNull String description,
+ int order,
+ long configurationId) {
+ ContentValues params = setParams(description, order, configurationId);
+ return insertIgnoreOnConflict(getTableName(), params);
+ }
+
+ /**
+ * Updates the field's description
+ *
+ * @param id ID of the field to change
+ * @param description new description
+ */
+ @Override
+ public void updateConfigFieldDescription(long id, @NonNull String description) {
+ ContentValues params = new ContentValues(1);
+ params.put(DESCRIPTION.getFieldName(), description);
+ scheduleUpdateExecutor(id, params);
+ }
+
+ /**
+ * Updates the field's order
+ *
+ * @param id ID of the field to change
+ * @param order new order
+ */
+ @Override
+ public void updateConfigurationOrder(long id, int order) {
+ ContentValues params = new ContentValues(1);
+ params.put(ORDER.getFieldName(), order);
+ scheduleUpdateExecutor(id, params);
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param description config field description
+ * @param order config field order
+ * @param configurationId config field parent configuration ID
+ *
+ * @return {@code ContentValues} with the params
+ *
+ * @see ContentValues
+ */
+ protected ContentValues setParams(@NonNull String description,
+ int order,
+ long configurationId) {
+ ContentValues params = new ContentValues(3);
+ params.put(DESCRIPTION.getFieldName(), description);
+ params.put(ORDER.getFieldName(), order);
+ params.put(CONFIGURATION.getFieldName(), configurationId);
+ return params;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getWhereId() {
+ return WHERE_ID;
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public abstract String getTag();
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public abstract String getTableName();
+
+ /**
+ * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfigFields}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see ConfigFields
+ */
+ @Override
+ public abstract GeneralObjectContainer getAllConfigFields();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsGetOperations.java
new file mode 100644
index 0000000..3d6c0ca
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsGetOperations.java
@@ -0,0 +1,59 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields;
+
+import javinator9889.securepass.data.configuration.IConfigFields;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface IConfigFieldsGetOperations {
+ /**
+ * Obtains the current description for the field
+ *
+ * @param id ID of the field where obtaining the data
+ * @return {@code String} with the name
+ */
+ String getConfigFieldDescription(long id);
+
+ /**
+ * Obtains the current field's order
+ *
+ * @param id ID of the field where obtaining the data
+ * @return {@code int} with the ordinal order
+ */
+ int getConfigFieldOrder(long id);
+
+ /**
+ * Obtains the current field's parent ID
+ *
+ * @param id ID of the field where obtaining the data
+ * @return {@code long} with the ID
+ */
+ long getConfigFieldConfigurationId(long id);
+
+ /**
+ * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfigFields}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see ObjectContainer
+ * @see javinator9889.securepass.data.configuration.ConfigFields
+ */
+ GeneralObjectContainer getAllConfigFields();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsSetOperations.java
new file mode 100644
index 0000000..3772105
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/IConfigFieldsSetOperations.java
@@ -0,0 +1,57 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.errors.database.NoJobsEnqueuedError;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface IConfigFieldsSetOperations {
+ /**
+ * Registers a new simple configuration field
+ *
+ * @param description field description
+ * @param order field order for displaying at UI
+ * @param configurationId parent configuration ID
+ *
+ * @return {@code long} with the new ID
+ */
+ long registerNewConfigField(@NonNull String description, int order, long configurationId);
+
+ /**
+ * Updates the field's description
+ *
+ * @param id ID of the field to change
+ * @param description new description
+ */
+ void updateConfigFieldDescription(long id, @NonNull String description);
+
+ /**
+ * Updates the field's order
+ *
+ * @param id ID of the field to change
+ * @param order new order
+ */
+ void updateConfigurationOrder(long id, int order);
+
+ /**
+ * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary
+ * when doing UPDATE operations
+ *
+ * @throws NoJobsEnqueuedError when there is no job added to the queue
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/imagesconfig/ImagesConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/imagesconfig/ImagesConfigOperations.java
new file mode 100644
index 0000000..223ad10
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/imagesconfig/ImagesConfigOperations.java
@@ -0,0 +1,103 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields.imagesconfig;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.IConfigFields;
+import javinator9889.securepass.data.configuration.ImagesConfig;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class ImagesConfigOperations extends ConfigFieldsOperations {
+ private static final String TAG = "ImagesConfig Operations";
+ private static final String TABLE_NAME = Constants.SQL.IMAGES_CONFIG.NAME;
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public ImagesConfigOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfigFields}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see javinator9889.securepass.data.configuration.ImagesConfig
+ */
+ @Override
+ public GeneralObjectContainer getAllConfigFields() {
+ GeneralObjectContainer configFields = new ObjectContainer<>();
+ try (Cursor imagesConfigCursor = getAll(TABLE_NAME, ORDER_BY)) {
+ Map imagesConfigColumns = constructMapFromCursor(imagesConfigCursor);
+ while (imagesConfigCursor.moveToNext()) {
+ long id = imagesConfigCursor.getLong(imagesConfigColumns.get(ID.getFieldName()));
+ String description = imagesConfigCursor.getString(
+ imagesConfigColumns.get(DESCRIPTION.getFieldName()));
+ int sortOrder =
+ imagesConfigCursor.getInt(imagesConfigColumns.get(ORDER.getFieldName()));
+ long configId = imagesConfigCursor.getLong(
+ imagesConfigColumns.get(CONFIGURATION.getFieldName()));
+ IConfigFields currentField = new ImagesConfig(id, description, sortOrder, configId);
+ configFields.storeObject(currentField);
+ }
+ }
+ return configFields;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/longtextconfig/LongTextConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/longtextconfig/LongTextConfigOperations.java
new file mode 100644
index 0000000..5bd9520
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/longtextconfig/LongTextConfigOperations.java
@@ -0,0 +1,104 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields.longtextconfig;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.IConfigFields;
+import javinator9889.securepass.data.configuration.LongTextConfig;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class LongTextConfigOperations extends ConfigFieldsOperations {
+ private static final String TAG = "LongTextConfig Operations";
+ private static final String TABLE_NAME = Constants.SQL.LONG_TEXT_CONFIG.NAME;
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public LongTextConfigOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfigFields}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see javinator9889.securepass.data.configuration.LongTextConfig
+ */
+ @Override
+ public GeneralObjectContainer getAllConfigFields() {
+ GeneralObjectContainer configFields = new ObjectContainer<>();
+ try (Cursor longTextConfigCursor = getAll(TABLE_NAME, ORDER_BY)) {
+ Map longTextColumns = constructMapFromCursor(longTextConfigCursor);
+ while (longTextConfigCursor.moveToNext()) {
+ long id = longTextConfigCursor.getLong(longTextColumns.get(ID.getFieldName()));
+ String description = longTextConfigCursor.getString(
+ longTextColumns.get(DESCRIPTION.getFieldName()));
+ int sortOrder =
+ longTextConfigCursor.getInt(longTextColumns.get(ORDER.getFieldName()));
+ long configId = longTextConfigCursor.getLong(
+ longTextColumns.get(CONFIGURATION.getFieldName()));
+ IConfigFields currentField =
+ new LongTextConfig(id, description, sortOrder, configId);
+ configFields.storeObject(currentField);
+ }
+ }
+ return configFields;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/passconfig/PassConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/passconfig/PassConfigOperations.java
new file mode 100644
index 0000000..19b0452
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/passconfig/PassConfigOperations.java
@@ -0,0 +1,103 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields.passconfig;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.IConfigFields;
+import javinator9889.securepass.data.configuration.PassConfig;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class PassConfigOperations extends ConfigFieldsOperations {
+ private static final String TAG = "PassConfig Operations";
+ private static final String TABLE_NAME = Constants.SQL.PASS_CONFIG.NAME;
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public PassConfigOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfigFields}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see javinator9889.securepass.data.configuration.PassConfig
+ */
+ @Override
+ public GeneralObjectContainer getAllConfigFields() {
+ GeneralObjectContainer configFields = new ObjectContainer<>();
+ try (Cursor passConfigsCursor = getAll(TABLE_NAME, ORDER_BY)) {
+ Map passConfigColumns = constructMapFromCursor(passConfigsCursor);
+ while (passConfigsCursor.moveToNext()) {
+ long id = passConfigsCursor.getLong(passConfigColumns.get(ID.getFieldName()));
+ String description = passConfigsCursor.getString(
+ passConfigColumns.get(DESCRIPTION.getFieldName()));
+ int order = passConfigsCursor.getInt(passConfigColumns.get(ORDER.getFieldName()));
+ long configurationId = passConfigsCursor.getLong(
+ passConfigColumns.get(CONFIGURATION.getFieldName()));
+ IConfigFields currentConfigField =
+ new PassConfig(id, description, order, configurationId);
+ configFields.storeObject(currentConfigField);
+ }
+ }
+ return configFields;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/smalltextconfig/SmallTextConfigOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/smalltextconfig/SmallTextConfigOperations.java
new file mode 100644
index 0000000..6a95456
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/configuration/configurationfields/smalltextconfig/SmallTextConfigOperations.java
@@ -0,0 +1,105 @@
+package javinator9889.securepass.io.database.operations.configuration.configurationfields.smalltextconfig;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.IConfigFields;
+import javinator9889.securepass.data.configuration.SmallTextConfig;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.io.database.operations.configuration.configurationfields.ConfigFieldsOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class SmallTextConfigOperations extends ConfigFieldsOperations {
+ private static final String TAG = "SmallTextConfig Operations";
+ private static final String TABLE_NAME = Constants.SQL.IMAGES_CONFIG.NAME;
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public SmallTextConfigOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains all config fields' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link IConfigFields}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see javinator9889.securepass.data.configuration.SmallTextConfig
+ */
+ @Override
+ public GeneralObjectContainer getAllConfigFields() {
+ GeneralObjectContainer configFields = new ObjectContainer<>();
+ try (Cursor smallTextConfigCursor = getAll(TABLE_NAME, ORDER_BY)) {
+ Map smallTextColumns = constructMapFromCursor(smallTextConfigCursor);
+ while (smallTextConfigCursor.moveToNext()) {
+ long id = smallTextConfigCursor.getLong(smallTextColumns.get(ID.getFieldName()));
+ String description =
+ smallTextConfigCursor.getString(
+ smallTextColumns.get(DESCRIPTION.getFieldName()));
+ int sortOrder =
+ smallTextConfigCursor.getInt(smallTextColumns.get(ORDER.getFieldName()));
+ long configId = smallTextConfigCursor.getLong(
+ smallTextColumns.get(CONFIGURATION.getFieldName()));
+ IConfigFields currentField =
+ new SmallTextConfig(id, description, sortOrder, configId);
+ configFields.storeObject(currentField);
+ }
+ }
+ return configFields;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java
new file mode 100644
index 0000000..33daddf
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/EntryOperations.java
@@ -0,0 +1,315 @@
+package javinator9889.securepass.io.database.operations.entry;
+
+import android.content.ContentValues;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.configuration.Configuration;
+import javinator9889.securepass.data.entry.Category;
+import javinator9889.securepass.data.entry.Entry;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants.SQL.ENTRY;
+import javinator9889.securepass.util.values.database.EntryFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 28/10/2018 - APP.
+ */
+public class EntryOperations extends CommonOperations implements
+ IEntrySetOperations, IEntryGetOperations {
+ private static final String TAG = "Entry Operations";
+ private static final String TABLE_NAME = ENTRY.NAME;
+ private static final EntryFields NAME = EntryFields.NAME;
+ private static final EntryFields ID = EntryFields.ID;
+ private static final EntryFields ICON = EntryFields.ICON;
+ private static final EntryFields CATEGORY = EntryFields.CATEGORY;
+ private static final EntryFields CONFIGURATION = EntryFields.CONFIGURATION;
+ private static final String ENTRY_WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseManager instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public EntryOperations(@NonNull DatabaseManager databaseManager) {
+ super(databaseManager);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @NonNull
+ @Override
+ public String getWhereId() {
+ return ENTRY_WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @NonNull
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Registers a new simple entry
+ *
+ * @param parentCategoryId category ID
+ * @param configId configuration ID
+ * @param entryName entry name
+ * @param icon entry icon
+ *
+ * @return long
with the new entry ID
+ *
+ * @see Category
+ * @see Configuration
+ */
+ @Override
+ public long registerNewEntry(long parentCategoryId,
+ long configId,
+ @NonNull String entryName,
+ @NonNull String icon) {
+ ContentValues params = setParams(entryName, icon, parentCategoryId, configId);
+ return insertReplaceOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates entry name
+ *
+ * @param entryId entry ID
+ * @param name new name
+ */
+ @Override
+ public void updateName(long entryId,
+ @NonNull String name) {
+ ContentValues params = new ContentValues(1);
+ params.put(NAME.getFieldName(), name);
+ scheduleUpdateExecutor(entryId, params);
+ }
+
+ /**
+ * Updates entry icon
+ *
+ * @param entryId entry ID
+ * @param icon new icon
+ */
+ @Override
+ public void updateIcon(long entryId,
+ @NonNull String icon) {
+ ContentValues params = new ContentValues(1);
+ params.put(ICON.getFieldName(), icon);
+ scheduleUpdateExecutor(entryId, params);
+ }
+
+ /**
+ * Updates entry category
+ *
+ * @param entryId entry ID
+ * @param categoryId new category ID
+ */
+ @Override
+ public void updateCategory(long entryId,
+ long categoryId) {
+ ContentValues params = new ContentValues(1);
+ params.put(CATEGORY.getFieldName(), categoryId);
+ scheduleUpdateExecutor(entryId, params);
+ }
+
+ /**
+ * Updates entry configuration
+ *
+ * @param entryId entry ID
+ * @param configurationId new configuration ID
+ */
+ @Override
+ public void updateConfiguration(long entryId,
+ long configurationId) {
+ ContentValues params = new ContentValues(1);
+ params.put(CONFIGURATION.getFieldName(), configurationId);
+ scheduleUpdateExecutor(entryId, params);
+ }
+
+ /**
+ * Removes the hole entry by the given ID
+ *
+ * @param entryId entry ID
+ */
+ @Override
+ public void removeEntry(long entryId) {
+ delete(TABLE_NAME, ID.getFieldName(), entryId);
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param entryName entry name
+ * @param entryIcon entry icon
+ * @param categoryId category ID
+ * @param configurationId configuration ID
+ *
+ * @return {@code ContentValues} with the params
+ *
+ * @see ContentValues
+ */
+ private ContentValues setParams(@NonNull String entryName,
+ @NonNull String entryIcon,
+ long categoryId,
+ long configurationId) {
+ ContentValues params = new ContentValues(4);
+ params.put(NAME.getFieldName(), entryName);
+ params.put(ICON.getFieldName(), entryIcon);
+ params.put(CATEGORY.getFieldName(), categoryId);
+ params.put(CONFIGURATION.getFieldName(), configurationId);
+ return params;
+ }
+
+ /**
+ * Obtains the entry name by using the given ID
+ *
+ * @param entryId entry ID
+ *
+ * @return {@code String} with the entry name - null if ID does not exist
+ */
+ @Override
+ @Nullable
+ public String getEntryName(long entryId) {
+ String name = null;
+ try (Cursor entryCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()), ENTRY_WHERE_ID,
+ whereArgs(entryId), null, null, ID.getFieldName() + " ASC")) {
+ Map entryColumns = constructMapFromCursor(entryCursor);
+ if (entryCursor.moveToNext())
+ name = entryCursor.getString(entryColumns.get(NAME.getFieldName()));
+ }
+ return name;
+ }
+
+ /**
+ * Obtains the entry icon by using the given ID
+ *
+ * @param entryId entry ID
+ *
+ * @return {@code String} with the entry icon - null if ID does not exist
+ */
+ @Override
+ @Nullable
+ public String getEntryIcon(long entryId) {
+ String icon = null;
+ try (Cursor iconCursor = get(TABLE_NAME, whereArgs(ICON.getFieldName()), ENTRY_WHERE_ID,
+ whereArgs(entryId), null, null, ID.getFieldName() + " ASC")) {
+ Map iconColumns = constructMapFromCursor(iconCursor);
+ if (iconCursor.moveToNext())
+ icon = iconCursor.getString(iconColumns.get(ICON.getFieldName()));
+ }
+ return icon;
+ }
+
+ /**
+ * Obtains the entry parent category by using the given ID
+ *
+ * @param entryId entry ID
+ *
+ * @return {@code long} with the category ID - 0 if ID does not exist
+ *
+ * @see Category
+ */
+ @Override
+ public long getEntryCategory(long entryId) {
+ long id = 0;
+ try (Cursor categoryCursor = get(TABLE_NAME, whereArgs(CATEGORY.getFieldName()),
+ ENTRY_WHERE_ID, whereArgs(entryId), null, null,
+ ID.getFieldName() + " ASC")) {
+ Map categoryColumns = constructMapFromCursor(categoryCursor);
+ if (categoryCursor.moveToNext())
+ id = categoryCursor.getLong(categoryColumns.get(CATEGORY.getFieldName()));
+ }
+ return id;
+ }
+
+ /**
+ * Obtains the entry configuration by using the given ID
+ *
+ * @param entryId entry ID
+ *
+ * @return {@code long} with the configuration ID - 0 if ID does not exist
+ *
+ * @see Configuration
+ */
+ @Override
+ public long getEntryConfiguration(long entryId) {
+ long id = 0;
+ try (Cursor configCursor = get(TABLE_NAME, whereArgs(CONFIGURATION.getFieldName()),
+ ENTRY_WHERE_ID, whereArgs(entryId), null, null,
+ ID.getFieldName() + " ASC")) {
+ Map configColumns = constructMapFromCursor(configCursor);
+ if (configCursor.moveToNext())
+ id = configCursor.getLong(configColumns.get(CONFIGURATION.getFieldName()));
+ }
+ return id;
+ }
+
+ /**
+ * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of {@link
+ * Entry}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see Entry
+ */
+ @Override
+ public GeneralObjectContainer getAllEntries() {
+ GeneralObjectContainer entries = new ObjectContainer<>();
+ try (Cursor entriesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map entriesColumns = constructMapFromCursor(entriesCursor);
+ while (entriesCursor.moveToNext()) {
+ long id = entriesCursor.getLong(entriesColumns.get(ID.getFieldName()));
+ String name = entriesCursor.getString(entriesColumns.get(NAME.getFieldName()));
+ String icon = entriesCursor.getString(entriesColumns.get(ICON.getFieldName()));
+ long categoryId = entriesCursor.getLong(entriesColumns.get(CATEGORY.getFieldName()));
+ long configurationId =
+ entriesCursor.getLong(entriesColumns.get(CONFIGURATION.getFieldName()));
+ Entry currentEntry = new Entry(id, name, icon, categoryId, configurationId);
+ entries.storeObject(currentEntry);
+ }
+ }
+ return entries;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java
new file mode 100644
index 0000000..76e981a
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntryGetOperations.java
@@ -0,0 +1,68 @@
+package javinator9889.securepass.io.database.operations.entry;
+
+import javinator9889.securepass.data.entry.Entry;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 28/10/2018 - APP.
+ */
+public interface IEntryGetOperations {
+ /**
+ * Obtains the entry name by using the given ID
+ *
+ * @param entryId entry ID
+ * @return {@code String} with the entry name
+ */
+ String getEntryName(long entryId);
+
+ /**
+ * Obtains the entry icon by using the given ID
+ *
+ * @param entryId entry ID
+ * @return {@code String} with the entry icon
+ */
+ String getEntryIcon(long entryId);
+
+ /**
+ * Obtains the entry parent category by using the given ID
+ *
+ * @param entryId entry ID
+ * @return {@code long} with the category ID
+ * @see javinator9889.securepass.data.entry.Category
+ */
+ long getEntryCategory(long entryId);
+
+ /**
+ * Obtains the entry configuration by using the given ID
+ *
+ * @param entryId entry ID
+ * @return {@code long} with the configuration ID
+ * @see javinator9889.securepass.data.configuration.Configuration
+ */
+ long getEntryConfiguration(long entryId);
+
+ /**
+ * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link Entry}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see Entry
+ */
+ GeneralObjectContainer getAllEntries();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java
new file mode 100644
index 0000000..65799ca
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/IEntrySetOperations.java
@@ -0,0 +1,81 @@
+package javinator9889.securepass.io.database.operations.entry;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 28/10/2018 - APP.
+ */
+public interface IEntrySetOperations {
+ /**
+ * Registers a new simple entry
+ *
+ * @param parentCategoryId category ID
+ * @param configId configuration ID
+ * @param entryName entry name
+ * @param icon entry icon
+ * @return long
with the new entry ID
+ * @see javinator9889.securepass.data.entry.Category
+ * @see javinator9889.securepass.data.configuration.Configuration
+ */
+ long registerNewEntry(long parentCategoryId, long configId, @NonNull String entryName,
+ @NonNull String icon);
+
+ /**
+ * Updates entry name
+ *
+ * @param entryId entry ID
+ * @param name new name
+ */
+ void updateName(long entryId, @NonNull String name);
+
+ /**
+ * Updates entry icon
+ *
+ * @param entryId entry ID
+ * @param icon new icon
+ */
+ void updateIcon(long entryId, @NonNull String icon);
+
+ /**
+ * Updates entry category
+ *
+ * @param entryId entry ID
+ * @param categoryId new category ID
+ */
+ void updateCategory(long entryId, long categoryId);
+
+ /**
+ * Updates entry configuration
+ *
+ * @param entryId entry ID
+ * @param configurationId new configuration ID
+ */
+ void updateConfiguration(long entryId, long configurationId);
+
+ /**
+ * Removes the hole entry by the given ID
+ *
+ * @param entryId entry ID
+ */
+ void removeEntry(long entryId);
+
+ /**
+ * Applies pending changes to the database - only necessary when doing UPDATE operations
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageGetOperations.java
new file mode 100644
index 0000000..3f46bbb
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageGetOperations.java
@@ -0,0 +1,66 @@
+package javinator9889.securepass.io.database.operations.entry.image;
+
+import javinator9889.securepass.data.entry.fields.Image;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface IImageGetOperations {
+ /**
+ * Obtains the image source by its ID
+ *
+ * @param imageId ID of the image to get the source
+ * @return {@code String} with the source
+ */
+ String getImageSource(long imageId);
+
+ /**
+ * Obtains the image description by its ID
+ *
+ * @param imageId ID of the image to get the description
+ * @return {@code String} with the description
+ */
+ String getImageDescription(long imageId);
+
+ /**
+ * Obtains the image order by its ID
+ *
+ * @param imageId ID of the image to get the order
+ * @return {@code int} with the ordinal order
+ */
+ int getImageOrder(long imageId);
+
+ /**
+ * Obtains the image parent entry ID
+ *
+ * @param imageId ID of the image to get the parent entry ID
+ * @return {@code long} with the entry ID
+ */
+ long getImageEntryId(long imageId);
+
+ /**
+ * Obtains all images' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link Image}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see Image
+ */
+ GeneralObjectContainer getAllImages();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageSetOperations.java
new file mode 100644
index 0000000..171c70f
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/IImageSetOperations.java
@@ -0,0 +1,74 @@
+package javinator9889.securepass.io.database.operations.entry.image;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.errors.database.NoJobsEnqueuedError;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface IImageSetOperations {
+ /**
+ * Registers a new simple image
+ *
+ * @param source image source
+ * @param description image description
+ * @param order ordinal order when showing on UI
+ * @param entryId parent entry ID
+ *
+ * @return {@code long} with the new image ID
+ */
+ long registerNewImage(@NonNull String source, @NonNull String description, int order,
+ long entryId);
+
+ /**
+ * Updates the image source of the provided ID
+ *
+ * @param imageId ID of the image to change source
+ * @param newSource new source
+ */
+ void updateImageSource(long imageId, @NonNull String newSource);
+
+ /**
+ * Updates the image description of the provided ID
+ *
+ * @param imageId ID of the image to change description
+ * @param newDescription new description
+ */
+ void updateImageDescription(long imageId, @NonNull String newDescription);
+
+ /**
+ * Updates the image order of the provided ID
+ *
+ * @param imageId ID of the image to change order
+ * @param newOrder new ordinal order
+ */
+ void updateImageOrder(long imageId, int newOrder);
+
+ /**
+ * Removes the image by its ID
+ *
+ * @param imageId ID of the image to delete
+ */
+ void removeImage(long imageId);
+
+ /**
+ * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary
+ * when doing UPDATE operations
+ *
+ * @throws NoJobsEnqueuedError when there is no job added to the queue
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/ImageOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/ImageOperations.java
new file mode 100644
index 0000000..b268b40
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/image/ImageOperations.java
@@ -0,0 +1,286 @@
+package javinator9889.securepass.io.database.operations.entry.image;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.entry.fields.Image;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.database.ImageFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class ImageOperations extends CommonOperations implements IImageSetOperations,
+ IImageGetOperations {
+ private static final String TAG = "Image Operations";
+ private static final String TABLE_NAME = Constants.SQL.IMAGE.NAME;
+ private static final ImageFields ID = ImageFields.ID;
+ private static final ImageFields SOURCE = ImageFields.SOURCE;
+ private static final ImageFields DESCRIPTION = ImageFields.DESCRIPTION;
+ private static final ImageFields ORDER = ImageFields.ORDER;
+ private static final ImageFields ENTRY = ImageFields.ENTRY;
+ private static final String WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public ImageOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getWhereId() {
+ return WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains the image source by its ID
+ *
+ * @param imageId ID of the image to get the source
+ *
+ * @return {@code String} with the source
+ */
+ @Override
+ public String getImageSource(long imageId) {
+ String source = null;
+ try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(SOURCE.getFieldName()), WHERE_ID,
+ whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) {
+ Map imagesColumns = constructMapFromCursor(imagesCursor);
+ if (imagesCursor.moveToNext())
+ source = imagesCursor.getString(imagesColumns.get(SOURCE.getFieldName()));
+ }
+ return source;
+ }
+
+ /**
+ * Obtains the image description by its ID
+ *
+ * @param imageId ID of the image to get the description
+ *
+ * @return {@code String} with the description
+ */
+ @Override
+ public String getImageDescription(long imageId) {
+ String description = null;
+ try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), WHERE_ID,
+ whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) {
+ Map imagesColumns = constructMapFromCursor(imagesCursor);
+ if (imagesCursor.moveToNext())
+ description = imagesCursor.getString(imagesColumns.get(DESCRIPTION.getFieldName()));
+ }
+ return description;
+ }
+
+ /**
+ * Obtains the image order by its ID
+ *
+ * @param imageId ID of the image to get the order
+ *
+ * @return {@code int} with the ordinal order
+ */
+ @Override
+ public int getImageOrder(long imageId) {
+ int order = -1;
+ try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID,
+ whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) {
+ Map imagesColumns = constructMapFromCursor(imagesCursor);
+ if (imagesCursor.moveToNext())
+ order = imagesCursor.getInt(imagesColumns.get(ORDER.getFieldName()));
+ }
+ return order;
+ }
+
+ /**
+ * Obtains the image parent entry ID
+ *
+ * @param imageId ID of the image to get the parent entry ID
+ *
+ * @return {@code long} with the entry ID
+ */
+ @Override
+ public long getImageEntryId(long imageId) {
+ long entryId = -1;
+ try (Cursor imagesCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID,
+ whereArgs(imageId), null, null, ID.getFieldName() + " ASC")) {
+ Map imagesColumns = constructMapFromCursor(imagesCursor);
+ if (imagesCursor.moveToNext())
+ entryId = imagesCursor.getLong(imagesColumns.get(ENTRY.getFieldName()));
+ }
+ return entryId;
+ }
+
+ /**
+ * Obtains all images' data and saves it inside a {@link GeneralObjectContainer} of {@link
+ * Image}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see Image
+ */
+ @Override
+ public GeneralObjectContainer getAllImages() {
+ GeneralObjectContainer images = new ObjectContainer<>();
+ try (Cursor imagesCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map imagesColumns = constructMapFromCursor(imagesCursor);
+ while (imagesCursor.moveToNext()) {
+ long id = imagesCursor.getLong(imagesColumns.get(ID.getFieldName()));
+ long entryId = imagesCursor.getLong(imagesColumns.get(ENTRY.getFieldName()));
+ String source = imagesCursor.getString(imagesColumns.get(SOURCE.getFieldName()));
+ String description = imagesCursor.getString(imagesColumns.get(DESCRIPTION.getFieldName()));
+ Image currentImage = new Image(id, entryId, source, description);
+ images.storeObject(currentImage);
+ }
+ }
+ return images;
+ }
+
+ /**
+ * Registers a new simple image
+ *
+ * @param source image source
+ * @param description image description
+ * @param order ordinal order when showing on UI
+ * @param entryId parent entry ID
+ *
+ * @return {@code long} with the new image ID
+ */
+ @Override
+ public long registerNewImage(@NonNull String source,
+ @NonNull String description,
+ int order,
+ long entryId) {
+ ContentValues params = setParams(source, description, order, entryId);
+ return insertReplaceOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates the image source of the provided ID
+ *
+ * @param imageId ID of the image to change source
+ * @param newSource new source
+ */
+ @Override
+ public void updateImageSource(long imageId, @NonNull String newSource) {
+ ContentValues params = new ContentValues(1);
+ params.put(SOURCE.getFieldName(), newSource);
+ scheduleUpdateExecutor(imageId, params);
+ }
+
+ /**
+ * Updates the image description of the provided ID
+ *
+ * @param imageId ID of the image to change description
+ * @param newDescription new description
+ */
+ @Override
+ public void updateImageDescription(long imageId, @NonNull String newDescription) {
+ ContentValues params = new ContentValues(1);
+ params.put(DESCRIPTION.getFieldName(), newDescription);
+ scheduleUpdateExecutor(imageId, params);
+ }
+
+ /**
+ * Updates the image order of the provided ID
+ *
+ * @param imageId ID of the image to change order
+ * @param newOrder new ordinal order
+ */
+ @Override
+ public void updateImageOrder(long imageId, int newOrder) {
+ ContentValues params = new ContentValues(1);
+ params.put(ORDER.getFieldName(), newOrder);
+ scheduleUpdateExecutor(imageId, params);
+ }
+
+ /**
+ * Removes the image by its ID
+ *
+ * @param imageId ID of the image to delete
+ */
+ @Override
+ public void removeImage(long imageId) {
+ delete(TABLE_NAME, ID.getFieldName(), imageId);
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param source image source
+ * @param description image description
+ * @param order ordinal order
+ * @param entryId entry ID
+ *
+ * @return {@code ContentValues} with the params
+ *
+ * @see ContentValues
+ */
+ private ContentValues setParams(@NonNull String source,
+ @NonNull String description,
+ int order,
+ long entryId) {
+ ContentValues params = new ContentValues(4);
+ params.put(SOURCE.getFieldName(), source);
+ params.put(DESCRIPTION.getFieldName(), description);
+ params.put(ORDER.getFieldName(), order);
+ params.put(ENTRY.getFieldName(), entryId);
+ return params;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordGetOperations.java
new file mode 100644
index 0000000..7c10e2f
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordGetOperations.java
@@ -0,0 +1,66 @@
+package javinator9889.securepass.io.database.operations.entry.password;
+
+import javinator9889.securepass.data.entry.fields.Password;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 01/11/2018 - APP.
+ */
+public interface IPasswordGetOperations {
+ /**
+ * Obtains the stored password
+ *
+ * @param passwordId ID of the password in the DB
+ * @return {@code String} with the password
+ */
+ String getPasswordPassword(long passwordId);
+
+ /**
+ * Obtains the password description
+ *
+ * @param passwordId ID of the password in DB
+ * @return {@code String} with the description
+ */
+ String getPasswordDescription(long passwordId);
+
+ /**
+ * Obtains the password ordinal order
+ *
+ * @param passwordId ID of the password in DB
+ * @return {@code int} with the order
+ */
+ int getPasswordOrder(long passwordId);
+
+ /**
+ * Obtains the password parent entry ID
+ *
+ * @param passwordId ID of the password in DB
+ * @return {@code long} with the entry ID
+ */
+ long getPasswordEntryId(long passwordId);
+
+ /**
+ * Obtains all passwords' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link Password}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see Password
+ */
+ GeneralObjectContainer getAllPasswords();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordSetOperations.java
new file mode 100644
index 0000000..f9af135
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/IPasswordSetOperations.java
@@ -0,0 +1,71 @@
+package javinator9889.securepass.io.database.operations.entry.password;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 01/11/2018 - APP.
+ */
+public interface IPasswordSetOperations {
+ /**
+ * Registers a new simple password entry
+ *
+ * @param password password to save
+ * @param description current entry description
+ * @param order ordinal order when showing it on UI
+ * @param entryId parent entry ID
+ * @return {@code long} with the new password ID
+ */
+ long registerNewPassword(@NonNull String password, @NonNull String description, int order,
+ long entryId);
+
+ /**
+ * Updates the saved password by using the given ID
+ *
+ * @param passwordId ID of the entry to change
+ * @param password new password to save
+ */
+ void updatePassword(long passwordId, @NonNull String password);
+
+ /**
+ * Updates the password description by using the given ID
+ *
+ * @param passwordId ID of the entry to change
+ * @param description new description
+ */
+ void updateDescription(long passwordId, @NonNull String description);
+
+ /**
+ * Updates the password order inside the entry
+ *
+ * @param passwordId ID of the password to change
+ * @param order new order
+ */
+ void updateSortOrder(long passwordId, int order);
+
+ /**
+ * Removes the hole password by using the given ID
+ *
+ * @param passwordId password ID to remove
+ */
+ void removePassword(long passwordId);
+
+ /**
+ * Applies pending changes to the database - only necessary when doing UPDATE operations
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/PasswordOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/PasswordOperations.java
new file mode 100644
index 0000000..1831faf
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/password/PasswordOperations.java
@@ -0,0 +1,281 @@
+package javinator9889.securepass.io.database.operations.entry.password;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.entry.fields.Password;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.database.PasswordFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 01/11/2018 - APP.
+ */
+public class PasswordOperations extends CommonOperations implements IPasswordSetOperations,
+ IPasswordGetOperations {
+ private static final String TAG = "Password Operations";
+ private static final String TABLE_NAME = Constants.SQL.PASSWORD.NAME;
+ private static final PasswordFields ID = PasswordFields.ID;
+ private static final PasswordFields PASSWORD = PasswordFields.PASSWORD;
+ private static final PasswordFields DESCRIPTION = PasswordFields.DESCRIPTION;
+ private static final PasswordFields ORDER = PasswordFields.ORDER;
+ private static final PasswordFields ENTRY = PasswordFields.ENTRY;
+ private static final String WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching
+ * {@link CommonOperations#CommonOperations(DatabaseManager) super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ * @see DatabaseManager
+ */
+ public PasswordOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getWhereId() {
+ return WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains the stored password
+ *
+ * @param passwordId ID of the password in the DB
+ * @return {@code String} with the password
+ */
+ @Override
+ public String getPasswordPassword(long passwordId) {
+ String password = null;
+ try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(PASSWORD.getFieldName()), WHERE_ID,
+ whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) {
+ Map passwordColumns = constructMapFromCursor(passwordCursor);
+ if (passwordCursor.moveToNext())
+ password = passwordCursor.getString(passwordColumns.get(PASSWORD.getFieldName()));
+ }
+ return password;
+ }
+
+ /**
+ * Obtains the password description
+ *
+ * @param passwordId ID of the password in DB
+ * @return {@code String} with the description
+ */
+ @Override
+ public String getPasswordDescription(long passwordId) {
+ String description = null;
+ try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()), WHERE_ID,
+ whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) {
+ Map passwordColumns = constructMapFromCursor(passwordCursor);
+ if (passwordCursor.moveToNext())
+ description = passwordCursor.getString(passwordColumns.get(DESCRIPTION.getFieldName()));
+ }
+ return description;
+ }
+
+ /**
+ * Obtains the password ordinal order
+ *
+ * @param passwordId ID of the password in DB
+ * @return {@code int} with the order
+ */
+ @Override
+ public int getPasswordOrder(long passwordId) {
+ int order = -1;
+ try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID,
+ whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) {
+ Map passwordColumns = constructMapFromCursor(passwordCursor);
+ if (passwordCursor.moveToNext())
+ order = passwordCursor.getInt(passwordColumns.get(ORDER.getFieldName()));
+ }
+ return order;
+ }
+
+ /**
+ * Obtains the password parent entry ID
+ *
+ * @param passwordId ID of the password in DB
+ * @return {@code long} with the entry ID
+ */
+ @Override
+ public long getPasswordEntryId(long passwordId) {
+ long entryId = -1;
+ try (Cursor passwordCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID,
+ whereArgs(passwordId), null, null, ID.getFieldName() + " ASC")) {
+ Map passwordColumns = constructMapFromCursor(passwordCursor);
+ if (passwordCursor.moveToNext())
+ entryId = passwordCursor.getLong(passwordColumns.get(ENTRY.getFieldName()));
+ }
+ return entryId;
+ }
+
+ /**
+ * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link Password}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see ObjectContainer
+ * @see Password
+ */
+ @Override
+ public GeneralObjectContainer getAllPasswords() {
+ GeneralObjectContainer passwords = new ObjectContainer<>();
+ try (Cursor passwordCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map passwordColumns = constructMapFromCursor(passwordCursor);
+ while (passwordCursor.moveToNext()) {
+ long id = passwordCursor.getLong(passwordColumns.get(ID.getFieldName()));
+ long entryId = passwordCursor.getLong(passwordColumns.get(ENTRY.getFieldName()));
+ String password =
+ passwordCursor.getString(passwordColumns.get(PASSWORD.getFieldName()));
+ String description =
+ passwordCursor.getString(passwordColumns.get(DESCRIPTION.getFieldName()));
+ Password currentPassword = new Password(id, entryId, password, description);
+ passwords.storeObject(currentPassword);
+ }
+ }
+ return passwords;
+ }
+
+ /**
+ * Registers a new simple password entry
+ *
+ * @param password password to save
+ * @param description current entry description
+ * @param order ordinal order when showing it on UI
+ * @param entryId parent entry ID
+ * @return {@code long} with the new password ID
+ */
+ @Override
+ public long registerNewPassword(@NonNull String password,
+ @NonNull String description,
+ int order,
+ long entryId) {
+ ContentValues params = setParams(password, description, order, entryId);
+ return insertReplaceOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates the saved password by using the given ID
+ *
+ * @param passwordId ID of the entry to change
+ * @param password new password to save
+ */
+ @Override
+ public void updatePassword(long passwordId, @NonNull String password) {
+ ContentValues params = new ContentValues(1);
+ params.put(PASSWORD.getFieldName(), password);
+ scheduleUpdateExecutor(passwordId, params);
+ }
+
+ /**
+ * Updates the password description by using the given ID
+ *
+ * @param passwordId ID of the entry to change
+ * @param description new description
+ */
+ @Override
+ public void updateDescription(long passwordId, @NonNull String description) {
+ ContentValues params = new ContentValues(1);
+ params.put(DESCRIPTION.getFieldName(), description);
+ scheduleUpdateExecutor(passwordId, params);
+ }
+
+ /**
+ * Updates the password order inside the entry
+ *
+ * @param passwordId ID of the password to change
+ * @param order new order
+ */
+ @Override
+ public void updateSortOrder(long passwordId, int order) {
+ ContentValues params = new ContentValues(1);
+ params.put(ORDER.getFieldName(), order);
+ scheduleUpdateExecutor(passwordId, params);
+ }
+
+ /**
+ * Removes the hole password by using the given ID
+ *
+ * @param passwordId password ID to remove
+ */
+ @Override
+ public void removePassword(long passwordId) {
+ delete(TABLE_NAME, ID.getFieldName(), passwordId);
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param password password
+ * @param description password description
+ * @param order ordinal order
+ * @param entryId entry ID
+ * @return {@code ContentValues} with the params
+ * @see ContentValues
+ */
+ private ContentValues setParams(@NonNull String password,
+ @NonNull String description,
+ int order,
+ long entryId) {
+ ContentValues params = new ContentValues(4);
+ params.put(PASSWORD.getFieldName(), password);
+ params.put(DESCRIPTION.getFieldName(), description);
+ params.put(ORDER.getFieldName(), order);
+ params.put(ENTRY.getFieldName(), entryId);
+ return params;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeGetOperations.java
new file mode 100644
index 0000000..6931db6
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeGetOperations.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2019 - present | SecurePass by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/02/2019 - SecurePass.
+ */
+package javinator9889.securepass.io.database.operations.entry.qrcode;
+
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.entry.QRCode;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+public interface IQRCodeGetOperations {
+ /**
+ * Obtains the QRCode name by using the given ID.
+ * @param id the QRCode ID.
+ * @return {@code String} with the name.
+ */
+ String getQRCodeName(long id);
+
+ /**
+ * Obtains the QRCode description by using the given ID - can be {@code null}.
+ * @param id the QRCode ID.
+ * @return {@code String} with the description.
+ */
+ @Nullable
+ String getQRCodeDescription(long id);
+
+ /**
+ * Obtains the QRCode data by using the given ID.
+ * @param id the QRCode ID.
+ * @return {@code String} with the data.
+ */
+ String getQRCodeData(long id);
+
+ /**
+ * Obtains the QRCode entry ID by using the QRCode ID.
+ * @param id the QRCode ID.
+ * @return {@code long} with the entry ID.
+ */
+ long getQRCodeEntryID(long id);
+
+ /**
+ * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link QRCode}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see QRCode
+ */
+ GeneralObjectContainer getAllQRCodes();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeSetOperations.java
new file mode 100644
index 0000000..7232ff7
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/IQRCodeSetOperations.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2019 - present | SecurePass by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/02/2019 - SecurePass.
+ */
+package javinator9889.securepass.io.database.operations.entry.qrcode;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+public interface IQRCodeSetOperations {
+ /**
+ * Registers a new QRCode on the database.
+ * @param entryId parent entry ID.
+ * @param name the name for the QRCode.
+ * @param description the optional description for the QRCode - can be {@code null}.
+ * @param qrCodeData the data of the QR.
+ * @return {@code long} with the created row ID.
+ */
+ long registerNewQRCode(long entryId,
+ @NonNull String name,
+ @Nullable String description,
+ @NonNull String qrCodeData);
+
+ /**
+ * Updates the QRCode name by using the given ID.
+ * @param id the QRCode ID.
+ * @param name the new name.
+ */
+ void updateName(long id, @NonNull String name);
+
+ /**
+ * Updates the QRCode description by using the given ID.
+ * @param id the QRCode ID.
+ * @param description the new description - can be {@code null}.
+ */
+ void updateDescription(long id, @Nullable String description);
+
+ /**
+ * Updates the QRCode data by using the given ID.
+ * @param id the QRCode ID.
+ * @param qrCodeData the new QRCode data.
+ */
+ void updateQrCodeData(long id, @NonNull String qrCodeData);
+
+ /**
+ * Removes the QRCode by using the given ID.
+ * @param id the QRCode row to delete.
+ */
+ void removeQRCode(long id);
+
+ /**
+ * Applies pending changes to the database - only necessary when doing UPDATE
+ * operations.
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/QRCodeOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/QRCodeOperations.java
new file mode 100644
index 0000000..52aa142
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/qrcode/QRCodeOperations.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright © 2019 - present | SecurePass by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/02/2019 - SecurePass.
+ */
+package javinator9889.securepass.io.database.operations.entry.qrcode;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.entry.QRCode;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.database.QRCodeFields;
+
+public class QRCodeOperations extends CommonOperations implements
+ IQRCodeSetOperations, IQRCodeGetOperations {
+ private static final String TAG = "Entry Operations";
+ private static final String TABLE_NAME = Constants.SQL.QR_CODE.NAME;
+ private static final QRCodeFields NAME = QRCodeFields.NAME;
+ private static final QRCodeFields ID = QRCodeFields.ID;
+ private static final QRCodeFields DESCRIPTION = QRCodeFields.DESCRIPTION;
+ private static final QRCodeFields DATA = QRCodeFields.DATA;
+ private static final QRCodeFields ENTRY = QRCodeFields.ENTRY;
+ private static final String QRCODE_WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Public constructor for creating this class - use this instead of {@link
+ * #newInstance(DatabaseManager)}.
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object.
+ * @see DatabaseManager
+ */
+ public QRCodeOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getWhereId() {
+ return QRCODE_WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains the QRCode name by using the given ID.
+ *
+ * @param id the QRCode ID.
+ * @return {@code String} with the name.
+ */
+ @Override
+ public String getQRCodeName(long id) {
+ String name = null;
+ try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(NAME.getFieldName()),
+ QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) {
+ Map qrCodeColumns = constructMapFromCursor(qrCodeCursor);
+ if (qrCodeCursor.moveToNext()) {
+ name = qrCodeCursor.getString(qrCodeColumns.get(NAME.getFieldName()));
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Obtains the QRCode description by using the given ID - can be {@code null}.
+ *
+ * @param id the QRCode ID.
+ * @return {@code String} with the description.
+ */
+ @Nullable
+ @Override
+ public String getQRCodeDescription(long id) {
+ String description = null;
+ try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()),
+ QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) {
+ Map qrCodeColumns = constructMapFromCursor(qrCodeCursor);
+ if (qrCodeCursor.moveToNext()) {
+ description = qrCodeCursor
+ .getString(qrCodeColumns.get(DESCRIPTION.getFieldName()));
+ }
+ }
+ return description;
+ }
+
+ /**
+ * Obtains the QRCode data by using the given ID.
+ *
+ * @param id the QRCode ID.
+ * @return {@code String} with the data.
+ */
+ @Override
+ public String getQRCodeData(long id) {
+ String qrCodeData = null;
+ try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(DATA.getFieldName()),
+ QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) {
+ Map qrCodeColumns = constructMapFromCursor(qrCodeCursor);
+ if (qrCodeCursor.moveToNext()) {
+ qrCodeData = qrCodeCursor
+ .getString(qrCodeColumns.get(DATA.getFieldName()));
+ }
+ }
+ return qrCodeData;
+ }
+
+ /**
+ * Obtains the QRCode entry ID by using the QRCode ID.
+ *
+ * @param id the QRCode ID.
+ * @return {@code long} with the entry ID.
+ */
+ @Override
+ public long getQRCodeEntryID(long id) {
+ long entryId = -1;
+ try (Cursor qrCodeCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()),
+ QRCODE_WHERE_ID, whereArgs(id), null, null, ID.getFieldName() + " ASC")) {
+ Map qrCodeColumns = constructMapFromCursor(qrCodeCursor);
+ if (qrCodeCursor.moveToNext()) {
+ entryId = qrCodeCursor.getLong(qrCodeColumns.get(ENTRY.getFieldName()));
+ }
+ }
+ return entryId;
+ }
+
+ /**
+ * Obtains all entries' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link QRCode}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see ObjectContainer
+ * @see QRCode
+ */
+ @Override
+ public GeneralObjectContainer getAllQRCodes() {
+ GeneralObjectContainer results = new ObjectContainer<>();
+ try (Cursor qrCodes = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map qrCodesColumns = constructMapFromCursor(qrCodes);
+ while (qrCodes.moveToNext()) {
+ long id = qrCodes.getLong(qrCodesColumns.get(ID.getFieldName()));
+ String name = qrCodes.getString(qrCodesColumns.get(NAME.getFieldName()));
+ String description = qrCodes
+ .getString(qrCodesColumns.get(DESCRIPTION.getFieldName()));
+ String data = qrCodes.getString(qrCodesColumns.get(DATA.getFieldName()));
+ long entryId = qrCodes.getLong(qrCodesColumns.get(ENTRY.getFieldName()));
+ QRCode currentCode = new QRCode(id, name, description, data, entryId);
+ results.storeObject(currentCode);
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Registers a new QRCode on the database.
+ *
+ * @param entryId parent entry ID.
+ * @param name the name for the QRCode.
+ * @param description the optional description for the QRCode - can be {@code null}.
+ * @param qrCodeData the data of the QR.
+ * @return {@code long} with the created row ID.
+ */
+ @Override
+ public long registerNewQRCode(long entryId,
+ @NonNull String name,
+ @Nullable String description,
+ @NonNull String qrCodeData) {
+ ContentValues params = setParams(entryId, name, description, qrCodeData);
+ return insertReplaceOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates the QRCode name by using the given ID.
+ *
+ * @param id the QRCode ID.
+ * @param name the new name.
+ */
+ @Override
+ public void updateName(long id, @NonNull String name) {
+ ContentValues params = new ContentValues(1);
+ params.put(NAME.getFieldName(), name);
+ scheduleUpdateExecutor(id, params);
+ }
+
+ /**
+ * Updates the QRCode description by using the given ID.
+ *
+ * @param id the QRCode ID.
+ * @param description the new description - can be {@code null}.
+ */
+ @Override
+ public void updateDescription(long id, @Nullable String description) {
+ ContentValues params = new ContentValues(1);
+ params.put(DESCRIPTION.getFieldName(), description);
+ scheduleUpdateExecutor(id, params);
+ }
+
+ /**
+ * Updates the QRCode data by using the given ID.
+ *
+ * @param id the QRCode ID.
+ * @param qrCodeData the new QRCode data.
+ */
+ @Override
+ public void updateQrCodeData(long id, @NonNull String qrCodeData) {
+ ContentValues params = new ContentValues(1);
+ params.put(DATA.getFieldName(), qrCodeData);
+ scheduleUpdateExecutor(id, params);
+ }
+
+ /**
+ * Removes the QRCode by using the given ID.
+ *
+ * @param id the QRCode row to delete.
+ */
+ @Override
+ public void removeQRCode(long id) {
+ delete(TABLE_NAME, ID.getFieldName(), id);
+ }
+
+ /**
+ * Generates a map with the provided params.
+ *
+ * @param entryId entry ID.
+ * @param name QRCode name.
+ * @param description QRCode description - can be {@code null}.
+ * @param data QRCode data.
+ *
+ * @return {@code ContentValues} with the params
+ *
+ * @see ContentValues
+ */
+ private ContentValues setParams(long entryId,
+ @NonNull String name,
+ @Nullable String description,
+ @NonNull String data) {
+ ContentValues params = new ContentValues(4);
+ params.put(ENTRY.getFieldName(), entryId);
+ params.put(NAME.getFieldName(), name);
+ params.put(DESCRIPTION.getFieldName(), description);
+ params.put(DATA.getFieldName(), data);
+ return params;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextGetOperations.java
new file mode 100644
index 0000000..8d7eae6
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextGetOperations.java
@@ -0,0 +1,53 @@
+package javinator9889.securepass.io.database.operations.entry.text;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface ITextGetOperations {
+ /**
+ * Obtains the text's field text
+ *
+ * @param textId ID of the text to obtain its data
+ * @return {@code String} with the text
+ */
+ String getTextText(long textId);
+
+ /**
+ * Obtains the text's description
+ *
+ * @param textId ID of the text to obtain its data
+ * @return {@code String} with the description
+ */
+ String getTextDescription(long textId);
+
+ /**
+ * Obtains the text's order
+ *
+ * @param textId ID of the text to obtain its data
+ * @return {@code int} with the ordinal order
+ */
+ int getTextOrder(long textId);
+
+ /**
+ * Obtains the text's entry ID
+ *
+ * @param textId ID of the text to obtain its data
+ * @return {@code long} with the entry ID
+ */
+ long getTextEntryId(long textId);
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextSetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextSetOperations.java
new file mode 100644
index 0000000..8eb0d27
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/ITextSetOperations.java
@@ -0,0 +1,74 @@
+package javinator9889.securepass.io.database.operations.entry.text;
+
+import androidx.annotation.NonNull;
+import javinator9889.securepass.errors.database.NoJobsEnqueuedError;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface ITextSetOperations {
+ /**
+ * Updates the current text by the provided one
+ *
+ * @param textId ID of the text field to change
+ * @param text new text
+ */
+ void updateTextText(long textId, @NonNull String text);
+
+ /**
+ * Updates the current text description
+ *
+ * @param textId ID of the text to change
+ * @param description new description
+ */
+ void updateTextDescription(long textId, @NonNull String description);
+
+ /**
+ * Updates the current text order
+ *
+ * @param textId ID of the text to change
+ * @param order new order
+ */
+ void updateTextOrder(long textId, int order);
+
+ /**
+ * Removes the text by using its ID
+ *
+ * @param textId ID of the text to remove
+ */
+ void removeText(long textId);
+
+ /**
+ * Registers a new simple small text
+ *
+ * @param text text to store in the DB
+ * @param description small text description
+ * @param order ordinal order
+ * @param entryId parent entry ID
+ *
+ * @return {@code long} with the new small text ID
+ */
+ long registerNewText(@NonNull String text, @NonNull String description, int order,
+ long entryId);
+
+ /**
+ * Runs the {@link com.github.javinator9889.threading.pools.ThreadsPooling} - only necessary
+ * when doing UPDATE operations
+ *
+ * @throws NoJobsEnqueuedError when there is no job added to the queue
+ */
+ void apply();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/ILongTextGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/ILongTextGetOperations.java
new file mode 100644
index 0000000..f019bef
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/ILongTextGetOperations.java
@@ -0,0 +1,35 @@
+package javinator9889.securepass.io.database.operations.entry.text.longtext;
+
+import javinator9889.securepass.data.entry.fields.LongText;
+import javinator9889.securepass.io.database.operations.entry.text.ITextGetOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface ILongTextGetOperations extends ITextGetOperations {
+ /**
+ * Obtains all long texts' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link LongText}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see LongText
+ */
+ GeneralObjectContainer getAllLongTexts();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/LongTextOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/LongTextOperations.java
new file mode 100644
index 0000000..7b5aeff
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/longtext/LongTextOperations.java
@@ -0,0 +1,289 @@
+package javinator9889.securepass.io.database.operations.entry.text.longtext;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.entry.fields.LongText;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.io.database.operations.entry.text.ITextSetOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.database.LongTextFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class LongTextOperations extends CommonOperations implements ITextSetOperations,
+ ILongTextGetOperations {
+ private static final String TAG = "LongText Operations";
+ private static final String TABLE_NAME = Constants.SQL.LONG_TEXT.NAME;
+ private static final LongTextFields ID = LongTextFields.ID;
+ private static final LongTextFields TEXT = LongTextFields.TEXT;
+ private static final LongTextFields DESCRIPTION = LongTextFields.DESCRIPTION;
+ private static final LongTextFields ORDER = LongTextFields.ORDER;
+ private static final LongTextFields ENTRY = LongTextFields.ENTRY;
+ private static final String WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public LongTextOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return String
with the tag name
+ */
+ @Override
+ public String getTag() {
+ return TAG;
+ }
+
+ /**
+ * Gets the WHERE ID clause for using {@link #scheduleUpdateExecutor(long, ContentValues)} -
+ * should be overridden
+ *
+ * @return {@code String} with the WHERE clause - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getWhereId() {
+ return WHERE_ID;
+ }
+
+ /**
+ * Gets the TABLE NAME for using {@link #scheduleUpdateExecutor(long, ContentValues)} - should
+ * be overridden
+ *
+ * @return {@code String} with the TABLE NAME - null if not defined
+ */
+ @Nullable
+ @Override
+ public String getTableName() {
+ return TABLE_NAME;
+ }
+
+ /**
+ * Obtains the text's field text
+ *
+ * @param textId ID of the text to obtain its data
+ *
+ * @return {@code String} with the text
+ */
+ @Override
+ public String getTextText(long textId) {
+ String text = null;
+ try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(ID.getFieldName()), WHERE_ID,
+ whereArgs(textId), null, null, ID.getFieldName() + " ASC")) {
+ Map longTextColumns = constructMapFromCursor(longTextsCursor);
+ if (longTextsCursor.moveToNext())
+ text = longTextsCursor.getString(longTextColumns.get(TEXT.getFieldName()));
+ }
+ return text;
+ }
+
+ /**
+ * Obtains the text's description
+ *
+ * @param textId ID of the text to obtain its data
+ *
+ * @return {@code String} with the description
+ */
+ @Override
+ public String getTextDescription(long textId) {
+ String description = null;
+ try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(DESCRIPTION.getFieldName()),
+ WHERE_ID, whereArgs(textId), null, null, ID.getFieldName() + " ASC")) {
+ Map longTextColumns = constructMapFromCursor(longTextsCursor);
+ if (longTextsCursor.moveToNext())
+ description = longTextsCursor.getString(longTextColumns.get(DESCRIPTION));
+ }
+ return description;
+ }
+
+ /**
+ * Obtains the text's order
+ *
+ * @param textId ID of the text to obtain its data
+ *
+ * @return {@code int} with the ordinal order
+ */
+ @Override
+ public int getTextOrder(long textId) {
+ int order = -1;
+ try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(ORDER.getFieldName()), WHERE_ID,
+ whereArgs(textId), null, null, ID.getFieldName() + " ASC")) {
+ Map longTextColumns = constructMapFromCursor(longTextsCursor);
+ if (longTextsCursor.moveToNext())
+ order = longTextsCursor.getInt(longTextColumns.get(ORDER.getFieldName()));
+ }
+ return order;
+ }
+
+ /**
+ * Obtains the text's entry ID
+ *
+ * @param textId ID of the text to obtain its data
+ *
+ * @return {@code long} with the entry ID
+ */
+ @Override
+ public long getTextEntryId(long textId) {
+ long entryId = -1;
+ try (Cursor longTextsCursor = get(TABLE_NAME, whereArgs(ENTRY.getFieldName()), WHERE_ID,
+ whereArgs(textId), null, null, ID.getFieldName() + " ASC")) {
+ Map longTextColumns = constructMapFromCursor(longTextsCursor);
+ if (longTextsCursor.moveToNext())
+ entryId = longTextsCursor.getLong(longTextColumns.get(ENTRY.getFieldName()));
+ }
+ return entryId;
+ }
+
+ /**
+ * Registers a new simple long text
+ *
+ * @param text text to store in the DB
+ * @param description long text description
+ * @param order ordinal order
+ * @param entryId parent entry ID
+ *
+ * @return {@code long} with the new long text ID
+ */
+ @Override
+ public long registerNewText(@NonNull String text,
+ @NonNull String description,
+ int order,
+ long entryId) {
+ ContentValues params = setParams(text, description, order, entryId);
+ return insertReplaceOnConflict(TABLE_NAME, params);
+ }
+
+ /**
+ * Updates the current text by the provided one
+ *
+ * @param textId ID of the text field to change
+ * @param text new text
+ */
+ @Override
+ public void updateTextText(long textId, @NonNull String text) {
+ ContentValues params = new ContentValues(1);
+ params.put(TEXT.getFieldName(), text);
+ scheduleUpdateExecutor(textId, params);
+ }
+
+ /**
+ * Updates the current text description
+ *
+ * @param textId ID of the text to change
+ * @param description new description
+ */
+ @Override
+ public void updateTextDescription(long textId, @NonNull String description) {
+ ContentValues params = new ContentValues(1);
+ params.put(DESCRIPTION.getFieldName(), description);
+ scheduleUpdateExecutor(textId, params);
+ }
+
+ /**
+ * Updates the current text order
+ *
+ * @param textId ID of the text to change
+ * @param order new order
+ */
+ @Override
+ public void updateTextOrder(long textId, int order) {
+ ContentValues params = new ContentValues(1);
+ params.put(ORDER.getFieldName(), order);
+ scheduleUpdateExecutor(textId, params);
+ }
+
+ /**
+ * Removes the text by using its ID
+ *
+ * @param textId ID of the text to remove
+ */
+ @Override
+ public void removeText(long textId) {
+ delete(TABLE_NAME, ID.getFieldName(), textId);
+ }
+
+ /**
+ * Obtains all long texts' data and saves it inside a {@link GeneralObjectContainer} of {@link
+ * LongText}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ *
+ * @see ObjectContainer
+ * @see LongText
+ */
+ @Override
+ public GeneralObjectContainer getAllLongTexts() {
+ GeneralObjectContainer longTexts = new ObjectContainer<>();
+ try (Cursor longTextsCursor = getAll(TABLE_NAME, ID.getFieldName() + " ASC")) {
+ Map longTextColumns = constructMapFromCursor(longTextsCursor);
+ while (longTextsCursor.moveToNext()) {
+ long id = longTextsCursor.getLong(longTextColumns.get(ID.getFieldName()));
+ String text = longTextsCursor.getString(longTextColumns.get(TEXT.getFieldName()));
+ String description =
+ longTextsCursor.getString(longTextColumns.get(DESCRIPTION.getFieldName()));
+ int order = longTextsCursor.getInt(longTextColumns.get(ORDER.getFieldName()));
+ long entryId = longTextsCursor.getLong(longTextColumns.get(ENTRY.getFieldName()));
+ LongText currentLongText = new LongText(id, entryId, text, description, order);
+ longTexts.storeObject(currentLongText);
+ }
+ }
+ return longTexts;
+ }
+
+ /**
+ * Generates a map with the provided params
+ *
+ * @param text text source
+ * @param description text description
+ * @param order ordinal order
+ * @param entryId entry ID
+ *
+ * @return {@code ContentValues} with the params
+ *
+ * @see ContentValues
+ */
+ private ContentValues setParams(@NonNull String text,
+ @NonNull String description,
+ int order,
+ long entryId) {
+ ContentValues params = new ContentValues(4);
+ params.put(TEXT.getFieldName(), text);
+ params.put(DESCRIPTION.getFieldName(), description);
+ params.put(ORDER.getFieldName(), order);
+ params.put(ENTRY.getFieldName(), entryId);
+ return params;
+ }
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/ISmallTextGetOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/ISmallTextGetOperations.java
new file mode 100644
index 0000000..8bc69a4
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/ISmallTextGetOperations.java
@@ -0,0 +1,35 @@
+package javinator9889.securepass.io.database.operations.entry.text.smalltext;
+
+import javinator9889.securepass.data.entry.fields.SmallText;
+import javinator9889.securepass.io.database.operations.entry.text.ITextGetOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public interface ISmallTextGetOperations extends ITextGetOperations {
+ /**
+ * Obtains all small texts' data and saves it inside a {@link GeneralObjectContainer} of
+ * {@link SmallText}
+ *
+ * @return {@code GeneralObjectContainer} of entries
+ * @see javinator9889.securepass.objects.ObjectContainer
+ * @see SmallText
+ */
+ GeneralObjectContainer getAllSmallTexts();
+}
diff --git a/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/SmallTextOperations.java b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/SmallTextOperations.java
new file mode 100644
index 0000000..378b5b7
--- /dev/null
+++ b/SecurePass/app/src/main/java/javinator9889/securepass/io/database/operations/entry/text/smalltext/SmallTextOperations.java
@@ -0,0 +1,289 @@
+package javinator9889.securepass.io.database.operations.entry.text.smalltext;
+
+import android.content.ContentValues;
+import android.util.Log;
+
+import net.sqlcipher.Cursor;
+
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import javinator9889.securepass.data.entry.fields.SmallText;
+import javinator9889.securepass.io.database.DatabaseManager;
+import javinator9889.securepass.io.database.operations.CommonOperations;
+import javinator9889.securepass.io.database.operations.entry.text.ITextSetOperations;
+import javinator9889.securepass.objects.GeneralObjectContainer;
+import javinator9889.securepass.objects.ObjectContainer;
+import javinator9889.securepass.util.values.Constants;
+import javinator9889.securepass.util.values.database.SmallTextFields;
+
+/**
+ * Copyright © 2018 - present | APP by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If
+ * not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 02/11/2018 - APP.
+ */
+public class SmallTextOperations extends CommonOperations implements ITextSetOperations,
+ ISmallTextGetOperations {
+ private static final String TAG = "SmallText Operations";
+ private static final String TABLE_NAME = Constants.SQL.SMALL_TEXT.NAME;
+ private static final SmallTextFields ID = SmallTextFields.ID;
+ private static final SmallTextFields TEXT = SmallTextFields.TEXT;
+ private static final SmallTextFields DESCRIPTION = SmallTextFields.DESCRIPTION;
+ private static final SmallTextFields ORDER = SmallTextFields.ORDER;
+ private static final SmallTextFields ENTRY = SmallTextFields.ENTRY;
+ private static final String WHERE_ID = ID.getFieldName() + "=?";
+
+ /**
+ * Available constructor, matching {@link CommonOperations#CommonOperations(DatabaseManager)
+ * super} one
+ *
+ * @param databaseInstance instance of the {@link DatabaseManager} object
+ *
+ * @see DatabaseManager
+ */
+ public SmallTextOperations(@NonNull DatabaseManager databaseInstance) {
+ super(databaseInstance);
+ }
+
+ /**
+ * Gets the tag for {@link Log} output - should be overridden
+ *
+ * @return