write prepped string to db. use display version everywhere else

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java | 32 
src/main/java/eu/siacs/conversations/entities/Contact.java              |  6 
src/main/java/eu/siacs/conversations/entities/Conversation.java         |  2 
src/main/java/eu/siacs/conversations/entities/Message.java              |  4 
src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java   | 16 
src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java                  | 17 
6 files changed, 45 insertions(+), 32 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java 🔗

@@ -185,8 +185,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		}
 
 		private void fillMap(SQLiteAxolotlStore store) {
-			List<Integer> deviceIds = store.getSubDeviceSessions(account.getJid().toBareJid().toString());
-			putDevicesForJid(account.getJid().toBareJid().toString(), deviceIds, store);
+			List<Integer> deviceIds = store.getSubDeviceSessions(account.getJid().toBareJid().toPreppedString());
+			putDevicesForJid(account.getJid().toBareJid().toPreppedString(), deviceIds, store);
 			for (Contact contact : account.getRoster().getContacts()) {
 				Jid bareJid = contact.getJid().toBareJid();
 				String address = bareJid.toString();
@@ -220,7 +220,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 
 		public void clearErrorFor(Jid jid) {
 			synchronized (MAP_LOCK) {
-				Map<Integer, FetchStatus> devices = this.map.get(jid.toBareJid().toString());
+				Map<Integer, FetchStatus> devices = this.map.get(jid.toBareJid().toPreppedString());
 				if (devices == null) {
 					return;
 				}
@@ -257,28 +257,28 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 	}
 
 	public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust) {
-		return axolotlStore.getContactKeysWithTrust(account.getJid().toBareJid().toString(), trust);
+		return axolotlStore.getContactKeysWithTrust(account.getJid().toBareJid().toPreppedString(), trust);
 	}
 
 	public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Jid jid) {
-		return axolotlStore.getContactKeysWithTrust(jid.toBareJid().toString(), trust);
+		return axolotlStore.getContactKeysWithTrust(jid.toBareJid().toPreppedString(), trust);
 	}
 
 	public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, List<Jid> jids) {
 		Set<IdentityKey> keys = new HashSet<>();
 		for(Jid jid : jids) {
-			keys.addAll(axolotlStore.getContactKeysWithTrust(jid.toString(), trust));
+			keys.addAll(axolotlStore.getContactKeysWithTrust(jid.toPreppedString(), trust));
 		}
 		return keys;
 	}
 
 	public long getNumTrustedKeys(Jid jid) {
-		return axolotlStore.getContactNumTrustedKeys(jid.toBareJid().toString());
+		return axolotlStore.getContactNumTrustedKeys(jid.toBareJid().toPreppedString());
 	}
 
 	public boolean anyTargetHasNoTrustedKeys(List<Jid> jids) {
 		for(Jid jid : jids) {
-			if (axolotlStore.getContactNumTrustedKeys(jid.toBareJid().toString()) == 0) {
+			if (axolotlStore.getContactNumTrustedKeys(jid.toBareJid().toPreppedString()) == 0) {
 				return true;
 			}
 		}
@@ -286,7 +286,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 	}
 
 	private AxolotlAddress getAddressForJid(Jid jid) {
-		return new AxolotlAddress(jid.toString(), 0);
+		return new AxolotlAddress(jid.toPreppedString(), 0);
 	}
 
 	private Set<XmppAxolotlSession> findOwnSessions() {
@@ -359,7 +359,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 	                                final XmppAxolotlSession.Trust from,
 	                                final XmppAxolotlSession.Trust to) {
 		for (Integer deviceId : deviceIds) {
-			AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toString(), deviceId);
+			AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId);
 			XmppAxolotlSession session = sessions.get(address);
 			if (session != null && session.getFingerprint() != null
 					&& session.getTrust() == from) {
@@ -381,13 +381,13 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 				publishOwnDeviceId(deviceIds);
 			}
 			for (Integer deviceId : deviceIds) {
-				AxolotlAddress ownDeviceAddress = new AxolotlAddress(jid.toBareJid().toString(), deviceId);
+				AxolotlAddress ownDeviceAddress = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId);
 				if (sessions.get(ownDeviceAddress) == null) {
 					buildSessionFromPEP(ownDeviceAddress);
 				}
 			}
 		}
-		Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toString()));
+		Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString()));
 		expiredDevices.removeAll(deviceIds);
 		setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.TRUSTED,
 				XmppAxolotlSession.Trust.INACTIVE_TRUSTED);
@@ -759,7 +759,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 	}
 
 	private void finishBuildingSessionsFromPEP(final AxolotlAddress address) {
-		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), 0);
+		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), 0);
 		if (!fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING)
 				&& !fetchStatusMap.getAll(address).containsValue(FetchStatus.PENDING)) {
 			FetchStatus report = null;
@@ -873,7 +873,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 		}
 		if (deviceIds.get(account.getJid().toBareJid()) != null) {
 			for (Integer ownId : this.deviceIds.get(account.getJid().toBareJid())) {
-				AxolotlAddress address = new AxolotlAddress(account.getJid().toBareJid().toString(), ownId);
+				AxolotlAddress address = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), ownId);
 				if (sessions.get(address) == null) {
 					IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey();
 					if (identityKey != null) {
@@ -933,12 +933,12 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
 	}
 
 	public boolean hasPendingKeyFetches(Account account, List<Jid> jids) {
-		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), 0);
+		AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), 0);
 		if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING)) {
 			return true;
 		}
 		for(Jid jid : jids) {
-			AxolotlAddress foreignAddress = new AxolotlAddress(jid.toBareJid().toString(), 0);
+			AxolotlAddress foreignAddress = new AxolotlAddress(jid.toBareJid().toPreppedString(), 0);
 			if (fetchStatusMap.getAll(foreignAddress).containsValue(FetchStatus.PENDING)) {
 				return true;
 			}

src/main/java/eu/siacs/conversations/entities/Contact.java 🔗

@@ -196,7 +196,7 @@ public class Contact implements ListItem, Blockable {
 			values.put(ACCOUNT, accountUuid);
 			values.put(SYSTEMNAME, systemName);
 			values.put(SERVERNAME, serverName);
-			values.put(JID, jid.toString());
+			values.put(JID, jid.toPreppedString());
 			values.put(OPTIONS, subscription);
 			values.put(SYSTEMACCOUNT, systemAccount);
 			values.put(PHOTOURI, photoUri);
@@ -209,10 +209,6 @@ public class Contact implements ListItem, Blockable {
 		}
 	}
 
-	public int getSubscription() {
-		return this.subscription;
-	}
-
 	public Account getAccount() {
 		return this.account;
 	}

src/main/java/eu/siacs/conversations/entities/Conversation.java 🔗

@@ -506,7 +506,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
 		values.put(NAME, name);
 		values.put(CONTACT, contactUuid);
 		values.put(ACCOUNT, accountUuid);
-		values.put(CONTACTJID, contactJid.toString());
+		values.put(CONTACTJID, contactJid.toPreppedString());
 		values.put(CREATED, created);
 		values.put(STATUS, status);
 		values.put(MODE, mode);

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -205,12 +205,12 @@ public class Message extends AbstractEntity {
 		if (counterpart == null) {
 			values.putNull(COUNTERPART);
 		} else {
-			values.put(COUNTERPART, counterpart.toString());
+			values.put(COUNTERPART, counterpart.toPreppedString());
 		}
 		if (trueCounterpart == null) {
 			values.putNull(TRUE_COUNTERPART);
 		} else {
-			values.put(TRUE_COUNTERPART, trueCounterpart.toString());
+			values.put(TRUE_COUNTERPART, trueCounterpart.toPreppedString());
 		}
 		values.put(BODY, body);
 		values.put(TIME_SENT, timeSent);

src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java 🔗

@@ -287,7 +287,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 					continue;
 				}
 				int ownDeviceId = Integer.valueOf(ownDeviceIdString);
-				AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), ownDeviceId);
+				AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), ownDeviceId);
 				deleteSession(db, account, ownAddress);
 				IdentityKeyPair identityKeyPair = loadOwnIdentityKeyPair(db, account);
 				if (identityKeyPair != null) {
@@ -345,7 +345,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 			try {
 				newJid = Jid.fromString(
 						cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))
-				).toString();
+				).toPreppedString();
 			} catch (InvalidJidException ignored) {
 				Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID "
 						+ cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))
@@ -370,7 +370,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 			try {
 				newJid = Jid.fromString(
 						cursor.getString(cursor.getColumnIndex(Contact.JID))
-				).toString();
+				).toPreppedString();
 			} catch (InvalidJidException ignored) {
 				Log.e(Config.LOGTAG, "Failed to migrate Contact JID "
 						+ cursor.getString(cursor.getColumnIndex(Contact.JID))
@@ -578,8 +578,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 	public Conversation findConversation(final Account account, final Jid contactJid) {
 		SQLiteDatabase db = this.getReadableDatabase();
 		String[] selectionArgs = {account.getUuid(),
-				contactJid.toBareJid().toString() + "/%",
-				contactJid.toBareJid().toString()
+				contactJid.toBareJid().toPreppedString() + "/%",
+				contactJid.toBareJid().toPreppedString()
 		};
 		Cursor cursor = db.query(Conversation.TABLENAME, null,
 				Conversation.ACCOUNT + "=? AND (" + Conversation.CONTACTJID
@@ -691,7 +691,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 				db.insert(Contact.TABLENAME, null, contact.getContentValues());
 			} else {
 				String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?";
-				String[] whereArgs = {account.getUuid(), contact.getJid().toString()};
+				String[] whereArgs = {account.getUuid(), contact.getJid().toPreppedString()};
 				db.delete(Contact.TABLENAME, where, whereArgs);
 			}
 		}
@@ -1025,7 +1025,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 	}
 
 	private IdentityKeyPair loadOwnIdentityKeyPair(SQLiteDatabase db, Account account) {
-		String name = account.getJid().toBareJid().toString();
+		String name = account.getJid().toBareJid().toPreppedString();
 		IdentityKeyPair identityKeyPair = null;
 		Cursor cursor = getIdentityKeyCursor(db, account, name, true);
 		if (cursor.getCount() != 0) {
@@ -1181,7 +1181,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 	}
 
 	public void storeOwnIdentityKeyPair(Account account, IdentityKeyPair identityKeyPair) {
-		storeIdentityKey(account, account.getJid().toBareJid().toString(), true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), XmppAxolotlSession.Trust.TRUSTED);
+		storeIdentityKey(account, account.getJid().toBareJid().toPreppedString(), true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), XmppAxolotlSession.Trust.TRUSTED);
 	}
 
 

src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java 🔗

@@ -21,6 +21,10 @@ public final class Jid {
 	private final String domainpart;
 	private final String resourcepart;
 
+	// It's much more efficient to store the ful JID as well as the parts instead of figuring them
+	// all out every time (since some characters are displayed but aren't used for comparisons).
+	private final String displayjid;
+
 	public String getLocalpart() {
 		return localpart;
 	}
@@ -69,6 +73,7 @@ public final class Jid {
 
 		Jid fromCache = Jid.cache.get(jid);
 		if (fromCache != null) {
+			displayjid = fromCache.displayjid;
 			localpart = fromCache.localpart;
 			domainpart = fromCache.domainpart;
 			resourcepart = fromCache.resourcepart;
@@ -89,6 +94,8 @@ public final class Jid {
 			throw new InvalidJidException(InvalidJidException.INVALID_CHARACTER);
 		}
 
+		String finaljid;
+
 		final int domainpartStart;
 		final int atLoc = jid.indexOf("@");
 		final int slashLoc = jid.indexOf("/");
@@ -96,6 +103,7 @@ public final class Jid {
 		// or there are one or more "@" signs but they're all in the resourcepart (eg. "example.net/@/rp@"):
 		if (atCount == 0 || (atCount > 0 && slashLoc != -1 && atLoc > slashLoc)) {
 			localpart = "";
+			finaljid = "";
 			domainpartStart = 0;
 		} else {
 			final String lp = jid.substring(0, atLoc);
@@ -108,6 +116,7 @@ public final class Jid {
 				throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
 			}
 			domainpartStart = atLoc + 1;
+			finaljid = lp + "@";
 		}
 
 		final String dp;
@@ -126,6 +135,7 @@ public final class Jid {
 			} catch (final StringprepException e) {
 				throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
 			}
+			finaljid = finaljid + dp + "/" + rp;
 		} else {
 			resourcepart = "";
 			try{
@@ -133,6 +143,7 @@ public final class Jid {
 			} catch (final StringprepException e) {
 				throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
 			}
+			finaljid = finaljid + dp;
 		}
 
 		// Remove trailing "." before storing the domain part.
@@ -156,6 +167,8 @@ public final class Jid {
 		}
 
 		Jid.cache.put(jid, this);
+
+		this.displayjid = finaljid;
 	}
 
 	public Jid toBareJid() {
@@ -178,6 +191,10 @@ public final class Jid {
 
 	@Override
 	public String toString() {
+		return displayjid;
+	}
+
+	public String toPreppedString() {
 		String out;
 		if (hasLocalpart()) {
 			out = localpart + '@' + domainpart;