aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu/siacs/conversations/entities')
-rw-r--r--src/eu/siacs/conversations/entities/AbstractEntity.java25
-rw-r--r--src/eu/siacs/conversations/entities/Account.java221
-rw-r--r--src/eu/siacs/conversations/entities/Contact.java296
-rw-r--r--src/eu/siacs/conversations/entities/Conversation.java284
-rw-r--r--src/eu/siacs/conversations/entities/Message.java144
-rw-r--r--src/eu/siacs/conversations/entities/MucOptions.java5
-rw-r--r--src/eu/siacs/conversations/entities/Presences.java76
7 files changed, 1051 insertions, 0 deletions
diff --git a/src/eu/siacs/conversations/entities/AbstractEntity.java b/src/eu/siacs/conversations/entities/AbstractEntity.java
new file mode 100644
index 00000000..0297fa66
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/AbstractEntity.java
@@ -0,0 +1,25 @@
+package eu.siacs.conversations.entities;
+
+import java.io.Serializable;
+
+import android.content.ContentValues;
+
+public abstract class AbstractEntity implements Serializable {
+
+ private static final long serialVersionUID = -1895605706690653719L;
+
+ public static final String UUID = "uuid";
+
+ protected String uuid;
+
+ public String getUuid() {
+ return this.uuid;
+ }
+
+ public abstract ContentValues getContentValues();
+
+ public boolean equals(AbstractEntity entity) {
+ return this.getUuid().equals(entity.getUuid());
+ }
+
+}
diff --git a/src/eu/siacs/conversations/entities/Account.java b/src/eu/siacs/conversations/entities/Account.java
new file mode 100644
index 00000000..a596aba1
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/Account.java
@@ -0,0 +1,221 @@
+package eu.siacs.conversations.entities;
+
+import java.security.interfaces.DSAPublicKey;
+
+import net.java.otr4j.crypto.OtrCryptoEngineImpl;
+import net.java.otr4j.crypto.OtrCryptoException;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import eu.siacs.conversations.crypto.OtrEngine;
+import eu.siacs.conversations.xmpp.XmppConnection;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.util.JsonReader;
+import android.util.Log;
+
+public class Account extends AbstractEntity{
+
+ private static final long serialVersionUID = 6174825093869578035L;
+
+ public static final String TABLENAME = "accounts";
+
+ public static final String USERNAME = "username";
+ public static final String SERVER = "server";
+ public static final String PASSWORD = "password";
+ public static final String OPTIONS = "options";
+ public static final String ROSTERVERSION = "rosterversion";
+ public static final String KEYS = "keys";
+
+ public static final int OPTION_USETLS = 0;
+ public static final int OPTION_DISABLED = 1;
+
+ public static final int STATUS_DISABLED = -1;
+ public static final int STATUS_OFFLINE = 0;
+ public static final int STATUS_ONLINE = 1;
+ public static final int STATUS_UNAUTHORIZED = 2;
+ public static final int STATUS_NOINTERNET = 3;
+ public static final int STATUS_TLS_ERROR = 4;
+ public static final int STATUS_SERVER_NOT_FOUND = 5;
+
+ protected String username;
+ protected String server;
+ protected String password;
+ protected int options = 0;
+ protected String rosterVersion;
+ protected String resource;
+ protected int status = 0;
+ protected JSONObject keys = new JSONObject();
+
+ protected boolean online = false;
+
+ transient OtrEngine otrEngine = null;
+ transient XmppConnection xmppConnection = null;
+
+ private String otrFingerprint;
+
+ public Account() {
+ this.uuid = "0";
+ }
+
+ public Account(String username, String server, String password) {
+ this(java.util.UUID.randomUUID().toString(),username,server,password,0,null,"");
+ }
+ public Account(String uuid, String username, String server,String password, int options, String rosterVersion, String keys) {
+ this.uuid = uuid;
+ this.username = username;
+ this.server = server;
+ this.password = password;
+ this.options = options;
+ this.rosterVersion = rosterVersion;
+ try {
+ this.keys = new JSONObject(keys);
+ } catch (JSONException e) {
+
+ }
+ }
+
+ public boolean isOptionSet(int option) {
+ return ((options & (1 << option)) != 0);
+ }
+
+ public void setOption(int option, boolean value) {
+ if (value) {
+ this.options |= 1 << option;
+ } else {
+ this.options &= ~(1 << option);
+ }
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getServer() {
+ return server;
+ }
+
+ public void setServer(String server) {
+ this.server = server;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public int getStatus() {
+ if (isOptionSet(OPTION_DISABLED)) {
+ return STATUS_DISABLED;
+ } else {
+ return this.status;
+ }
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ public String getJid() {
+ return username+"@"+server;
+ }
+
+ public JSONObject getKeys() {
+ return keys;
+ }
+
+ public boolean setKey(String keyName, String keyValue) {
+ try {
+ this.keys.put(keyName, keyValue);
+ return true;
+ } catch (JSONException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public ContentValues getContentValues() {
+ ContentValues values = new ContentValues();
+ values.put(UUID,uuid);
+ values.put(USERNAME, username);
+ values.put(SERVER, server);
+ values.put(PASSWORD, password);
+ values.put(OPTIONS,options);
+ values.put(KEYS,this.keys.toString());
+ values.put(ROSTERVERSION,rosterVersion);
+ return values;
+ }
+
+ public static Account fromCursor(Cursor cursor) {
+ return new Account(cursor.getString(cursor.getColumnIndex(UUID)),
+ cursor.getString(cursor.getColumnIndex(USERNAME)),
+ cursor.getString(cursor.getColumnIndex(SERVER)),
+ cursor.getString(cursor.getColumnIndex(PASSWORD)),
+ cursor.getInt(cursor.getColumnIndex(OPTIONS)),
+ cursor.getString(cursor.getColumnIndex(ROSTERVERSION)),
+ cursor.getString(cursor.getColumnIndex(KEYS))
+ );
+ }
+
+
+ public OtrEngine getOtrEngine(Context context) {
+ if (otrEngine==null) {
+ otrEngine = new OtrEngine(context,this);
+ }
+ return this.otrEngine;
+ }
+
+ public XmppConnection getXmppConnection() {
+ return this.xmppConnection;
+ }
+
+ public void setXmppConnection(XmppConnection connection) {
+ this.xmppConnection = connection;
+ }
+
+ public String getFullJid() {
+ return this.getJid()+"/"+this.resource;
+ }
+
+ public String getOtrFingerprint() {
+ if (this.otrFingerprint == null) {
+ try {
+ DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine.getPublicKey();
+ StringBuilder builder = new StringBuilder(new OtrCryptoEngineImpl().getFingerprint(pubkey));
+ builder.insert(8, " ");
+ builder.insert(17, " ");
+ builder.insert(26, " ");
+ builder.insert(35, " ");
+ this.otrFingerprint = builder.toString();
+ } catch (OtrCryptoException e) {
+
+ }
+ }
+ return this.otrFingerprint;
+ }
+
+ public String getRosterVersion() {
+ if (this.rosterVersion==null) {
+ return "";
+ } else {
+ return this.rosterVersion;
+ }
+ }
+
+ public void setRosterVersion(String version) {
+ this.rosterVersion = version;
+ }
+}
diff --git a/src/eu/siacs/conversations/entities/Contact.java b/src/eu/siacs/conversations/entities/Contact.java
new file mode 100644
index 00000000..0eed39ed
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/Contact.java
@@ -0,0 +1,296 @@
+package eu.siacs.conversations.entities;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import eu.siacs.conversations.xml.Element;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+
+public class Contact extends AbstractEntity implements Serializable {
+ private static final long serialVersionUID = -4570817093119419962L;
+
+ public static final String TABLENAME = "contacts";
+
+ public static final String DISPLAYNAME = "name";
+ public static final String JID = "jid";
+ public static final String SUBSCRIPTION = "subscription";
+ public static final String SYSTEMACCOUNT = "systemaccount";
+ public static final String PHOTOURI = "photouri";
+ public static final String KEYS = "pgpkey";
+ public static final String PRESENCES = "presences";
+ public static final String ACCOUNT = "accountUuid";
+
+ protected String accountUuid;
+ protected String displayName;
+ protected String jid;
+ protected int subscription = 0;
+ protected String systemAccount;
+ protected String photoUri;
+ protected JSONObject keys = new JSONObject();
+ protected Presences presences = new Presences();
+
+ protected Account account;
+
+ protected boolean inRoster = true;
+
+ public Contact(Account account, String displayName, String jid,
+ String photoUri) {
+ if (account == null) {
+ this.accountUuid = null;
+ } else {
+ this.accountUuid = account.getUuid();
+ }
+ this.account = account;
+ this.displayName = displayName;
+ this.jid = jid;
+ this.photoUri = photoUri;
+ this.uuid = java.util.UUID.randomUUID().toString();
+ }
+
+ public Contact(String uuid, String account, String displayName, String jid,
+ int subscription, String photoUri, String systemAccount,
+ String keys, String presences) {
+ this.uuid = uuid;
+ this.accountUuid = account;
+ this.displayName = displayName;
+ this.jid = jid;
+ this.subscription = subscription;
+ this.photoUri = photoUri;
+ this.systemAccount = systemAccount;
+ if (keys == null) {
+ keys = "";
+ }
+ try {
+ this.keys = new JSONObject(keys);
+ } catch (JSONException e) {
+ this.keys = new JSONObject();
+ }
+ this.presences = Presences.fromJsonString(presences);
+ }
+
+ public String getDisplayName() {
+ return this.displayName;
+ }
+
+ public String getProfilePhoto() {
+ return this.photoUri;
+ }
+
+ public String getJid() {
+ return this.jid;
+ }
+
+ public boolean match(String needle) {
+ return (jid.toLowerCase().contains(needle.toLowerCase()) || (displayName
+ .toLowerCase().contains(needle.toLowerCase())));
+ }
+
+ @Override
+ public ContentValues getContentValues() {
+ ContentValues values = new ContentValues();
+ values.put(UUID, uuid);
+ values.put(ACCOUNT, accountUuid);
+ values.put(DISPLAYNAME, displayName);
+ values.put(JID, jid);
+ values.put(SUBSCRIPTION, subscription);
+ values.put(SYSTEMACCOUNT, systemAccount);
+ values.put(PHOTOURI, photoUri);
+ values.put(KEYS, keys.toString());
+ values.put(PRESENCES, presences.toJsonString());
+ return values;
+ }
+
+ public static Contact fromCursor(Cursor cursor) {
+ return new Contact(cursor.getString(cursor.getColumnIndex(UUID)),
+ cursor.getString(cursor.getColumnIndex(ACCOUNT)),
+ cursor.getString(cursor.getColumnIndex(DISPLAYNAME)),
+ cursor.getString(cursor.getColumnIndex(JID)),
+ cursor.getInt(cursor.getColumnIndex(SUBSCRIPTION)),
+ cursor.getString(cursor.getColumnIndex(PHOTOURI)),
+ cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
+ cursor.getString(cursor.getColumnIndex(KEYS)),
+ cursor.getString(cursor.getColumnIndex(PRESENCES)));
+ }
+
+ public int getSubscription() {
+ return this.subscription;
+ }
+
+ public void setSystemAccount(String account) {
+ this.systemAccount = account;
+ }
+
+ public void setAccount(Account account) {
+ this.account = account;
+ this.accountUuid = account.getUuid();
+ }
+
+ public Account getAccount() {
+ return this.account;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public boolean couldBeMuc() {
+ String[] split = this.getJid().split("@");
+ if (split.length != 2) {
+ return false;
+ } else {
+ String[] domainParts = split[1].split("\\.");
+ if (domainParts.length < 3) {
+ return false;
+ } else {
+ return (domainParts[0].equals("conf")
+ || domainParts[0].equals("conference") || domainParts[0]
+ .equals("muc"));
+ }
+ }
+ }
+
+ public Hashtable<String, Integer> getPresences() {
+ return this.presences.getPresences();
+ }
+
+ public void updatePresence(String resource, int status) {
+ this.presences.updatePresence(resource, status);
+ }
+
+ public void removePresence(String resource) {
+ this.presences.removePresence(resource);
+ }
+
+ public int getMostAvailableStatus() {
+ return this.presences.getMostAvailableStatus();
+ }
+
+ public void setPresences(Presences pres) {
+ this.presences = pres;
+ }
+
+ public void setPhotoUri(String uri) {
+ this.photoUri = uri;
+ }
+
+ public void setDisplayName(String name) {
+ this.displayName = name;
+ }
+
+ public String getSystemAccount() {
+ return systemAccount;
+ }
+
+ public Set<String> getOtrFingerprints() {
+ Set<String> set = new HashSet<String>();
+ try {
+ if (this.keys.has("otr_fingerprints")) {
+ JSONArray fingerprints = this.keys.getJSONArray("otr_fingerprints");
+ for (int i = 0; i < fingerprints.length(); ++i) {
+ set.add(fingerprints.getString(i));
+ }
+ }
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return set;
+ }
+
+ public void addOtrFingerprint(String print) {
+ try {
+ JSONArray fingerprints;
+ if (!this.keys.has("otr_fingerprints")) {
+ fingerprints = new JSONArray();
+
+ } else {
+ fingerprints = this.keys.getJSONArray("otr_fingerprints");
+ }
+ fingerprints.put(print);
+ this.keys.put("otr_fingerprints", fingerprints);
+ } catch (JSONException e) {
+
+ }
+ }
+
+ public void setPgpKeyId(long keyId) {
+ try {
+ this.keys.put("pgp_keyid", keyId);
+ } catch (JSONException e) {
+
+ }
+ }
+
+ public long getPgpKeyId() {
+ if (this.keys.has("pgp_keyid")) {
+ try {
+ return this.keys.getLong("pgp_keyid");
+ } catch (JSONException e) {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ public void setSubscriptionOption(int option) {
+ this.subscription |= 1 << option;
+ }
+
+ public void resetSubscriptionOption(int option) {
+ this.subscription &= ~(1 << option);
+ }
+
+ public boolean getSubscriptionOption(int option) {
+ return ((this.subscription & (1 << option)) != 0);
+ }
+
+ public void parseSubscriptionFromElement(Element item) {
+ String ask = item.getAttribute("ask");
+ String subscription = item.getAttribute("subscription");
+
+ if (subscription!=null) {
+ if (subscription.equals("to")) {
+ this.resetSubscriptionOption(Contact.Subscription.FROM);
+ this.setSubscriptionOption(Contact.Subscription.TO);
+ } else if (subscription.equals("from")) {
+ this.resetSubscriptionOption(Contact.Subscription.TO);
+ this.setSubscriptionOption(Contact.Subscription.FROM);
+ } else if (subscription.equals("both")) {
+ this.setSubscriptionOption(Contact.Subscription.TO);
+ this.setSubscriptionOption(Contact.Subscription.FROM);
+ }
+ }
+
+ if ((ask!=null)&&(ask.equals("subscribe"))) {
+ this.setSubscriptionOption(Contact.Subscription.ASKING);
+ } else {
+ this.resetSubscriptionOption(Contact.Subscription.ASKING);
+ }
+ }
+
+
+ public class Subscription {
+ public static final int TO = 0;
+ public static final int FROM = 1;
+ public static final int ASKING = 2;
+ public static final int PREEMPTIVE_GRANT = 4;
+ }
+
+
+ public void flagAsNotInRoster() {
+ this.inRoster = false;
+ }
+
+ public boolean isInRoster() {
+ return this.inRoster;
+ }
+}
diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java
new file mode 100644
index 00000000..d1186a7d
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/Conversation.java
@@ -0,0 +1,284 @@
+package eu.siacs.conversations.entities;
+
+import java.security.interfaces.DSAPublicKey;
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.siacs.conversations.crypto.OtrEngine;
+import eu.siacs.conversations.xmpp.XmppConnection;
+
+import net.java.otr4j.OtrException;
+import net.java.otr4j.crypto.OtrCryptoEngineImpl;
+import net.java.otr4j.crypto.OtrCryptoException;
+import net.java.otr4j.session.SessionID;
+import net.java.otr4j.session.SessionImpl;
+import net.java.otr4j.session.SessionStatus;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+public class Conversation extends AbstractEntity {
+
+ private static final long serialVersionUID = -6727528868973996739L;
+
+ public static final String TABLENAME = "conversations";
+
+ public static final int STATUS_AVAILABLE = 0;
+ public static final int STATUS_ARCHIVED = 1;
+ public static final int STATUS_DELETED = 2;
+
+ public static final int MODE_MULTI = 1;
+ public static final int MODE_SINGLE = 0;
+
+ public static final String NAME = "name";
+ public static final String ACCOUNT = "accountUuid";
+ public static final String CONTACT = "contactUuid";
+ public static final String CONTACTJID = "contactJid";
+ public static final String STATUS = "status";
+ public static final String CREATED = "created";
+ public static final String MODE = "mode";
+
+ private String name;
+ private String contactUuid;
+ private String accountUuid;
+ private String contactJid;
+ private int status;
+ private long created;
+ private int mode;
+
+ private transient List<Message> messages = null;
+ private transient Account account = null;
+ private transient Contact contact;
+
+ private transient SessionImpl otrSession;
+
+ private transient String otrFingerprint = null;
+
+ public int nextMessageEncryption = Message.ENCRYPTION_NONE;
+
+ private transient MucOptions mucOptions = null;
+
+ public Conversation(String name, Account account,
+ String contactJid, int mode) {
+ this(java.util.UUID.randomUUID().toString(), name, null, account.getUuid(), contactJid, System
+ .currentTimeMillis(), STATUS_AVAILABLE,mode);
+ this.account = account;
+ }
+
+ public Conversation(String uuid, String name, String contactUuid,
+ String accountUuid, String contactJid, long created, int status, int mode) {
+ this.uuid = uuid;
+ this.name = name;
+ this.contactUuid = contactUuid;
+ this.accountUuid = accountUuid;
+ this.contactJid = contactJid;
+ this.created = created;
+ this.status = status;
+ this.mode = mode;
+ }
+
+ public List<Message> getMessages() {
+ if (messages == null) this.messages = new ArrayList<Message>(); //prevent null pointer
+
+ //populate with Conversation (this)
+
+ for(Message msg : messages) {
+ msg.setConversation(this);
+ }
+
+ return messages;
+ }
+
+ public boolean isRead() {
+ if ((this.messages == null)||(this.messages.size() == 0)) return true;
+ return this.messages.get(this.messages.size() - 1).isRead();
+ }
+
+ public void markRead() {
+ if (this.messages == null) return;
+ for(int i = this.messages.size() -1; i >= 0; --i) {
+ if (messages.get(i).isRead()) return;
+ this.messages.get(i).markRead();
+ }
+ }
+
+ public Message getLatestMessage() {
+ if ((this.messages == null)||(this.messages.size()==0)) {
+ Message message = new Message(this,"",Message.ENCRYPTION_NONE);
+ message.setTime(getCreated());
+ return message;
+ } else {
+ return this.messages.get(this.messages.size() - 1);
+ }
+ }
+
+ public void setMessages(List<Message> msgs) {
+ this.messages = msgs;
+ }
+
+ public String getName() {
+ if (this.contact!=null) {
+ return this.contact.getDisplayName();
+ } else {
+ return this.name;
+ }
+ }
+
+ public String getProfilePhotoString() {
+ if (this.contact==null) {
+ return null;
+ } else {
+ return this.contact.getProfilePhoto();
+ }
+ }
+
+ public String getAccountUuid() {
+ return this.accountUuid;
+ }
+
+ public Account getAccount() {
+ return this.account;
+ }
+
+ public Contact getContact() {
+ return this.contact;
+ }
+
+ public void setContact(Contact contact) {
+ this.contact = contact;
+ if (contact!=null) {
+ this.contactUuid = contact.getUuid();
+ }
+ }
+
+ public void setAccount(Account account) {
+ this.account = account;
+ }
+
+ public String getContactJid() {
+ return this.contactJid;
+ }
+
+ public Uri getProfilePhotoUri() {
+ if (this.getProfilePhotoString() != null) {
+ return Uri.parse(this.getProfilePhotoString());
+ }
+ return null;
+ }
+
+ public int getStatus() {
+ return this.status;
+ }
+
+ public long getCreated() {
+ return this.created;
+ }
+
+ public ContentValues getContentValues() {
+ ContentValues values = new ContentValues();
+ values.put(UUID, uuid);
+ values.put(NAME, name);
+ values.put(CONTACT, contactUuid);
+ values.put(ACCOUNT, accountUuid);
+ values.put(CONTACTJID, contactJid);
+ values.put(CREATED, created);
+ values.put(STATUS, status);
+ values.put(MODE,mode);
+ return values;
+ }
+
+ public static Conversation fromCursor(Cursor cursor) {
+ return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)),
+ cursor.getString(cursor.getColumnIndex(NAME)),
+ cursor.getString(cursor.getColumnIndex(CONTACT)),
+ cursor.getString(cursor.getColumnIndex(ACCOUNT)),
+ cursor.getString(cursor.getColumnIndex(CONTACTJID)),
+ cursor.getLong(cursor.getColumnIndex(CREATED)),
+ cursor.getInt(cursor.getColumnIndex(STATUS)),
+ cursor.getInt(cursor.getColumnIndex(MODE)));
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public int getMode() {
+ return this.mode;
+ }
+
+ public void setMode(int mode) {
+ this.mode = mode;
+ }
+
+ public void startOtrSession(Context context, String presence) {
+ Log.d("xmppService","starting otr session with "+presence);
+ SessionID sessionId = new SessionID(this.getContactJid(),presence,"xmpp");
+ this.otrSession = new SessionImpl(sessionId, getAccount().getOtrEngine(context));
+ try {
+ this.otrSession.startSession();
+ } catch (OtrException e) {
+ Log.d("xmppServic","couldnt start otr");
+ }
+ }
+
+ public SessionImpl getOtrSession() {
+ return this.otrSession;
+ }
+
+ public void resetOtrSession() {
+ this.otrSession = null;
+ }
+
+ public void endOtrIfNeeded() throws OtrException {
+ if (this.otrSession!=null) {
+ if (this.otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) {
+ this.otrSession.endSession();
+ }
+ }
+ this.resetOtrSession();
+ }
+
+ public boolean hasValidOtrSession() {
+ if (this.otrSession == null) {
+ return false;
+ } else {
+ String foreignPresence = this.otrSession.getSessionID().getUserID();
+ if (!getContact().getPresences().containsKey(foreignPresence)) {
+ this.resetOtrSession();
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public String getOtrFingerprint() {
+ if (this.otrFingerprint == null) {
+ try {
+ DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession().getRemotePublicKey();
+ StringBuilder builder = new StringBuilder(new OtrCryptoEngineImpl().getFingerprint(remotePubKey));
+ builder.insert(8, " ");
+ builder.insert(17, " ");
+ builder.insert(26, " ");
+ builder.insert(35, " ");
+ this.otrFingerprint = builder.toString();
+ } catch (OtrCryptoException e) {
+
+ }
+ }
+ return this.otrFingerprint;
+ }
+
+ public MucOptions getMucOptions() {
+ if (this.mucOptions == null) {
+ this.mucOptions = new MucOptions();
+ }
+ return this.mucOptions ;
+ }
+
+ public void resetMucOptions() {
+ this.mucOptions = null;
+ }
+}
diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java
new file mode 100644
index 00000000..0fce2a5b
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/Message.java
@@ -0,0 +1,144 @@
+package eu.siacs.conversations.entities;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+
+public class Message extends AbstractEntity {
+
+ private static final long serialVersionUID = 7222081895167103025L;
+
+ public static final String TABLENAME = "messages";
+
+ public static final int STATUS_RECIEVED = 0;
+ public static final int STATUS_UNSEND = 1;
+ public static final int STATUS_SEND = 2;
+ public static final int STATUS_ERROR = 3;
+
+ public static final int ENCRYPTION_NONE = 0;
+ public static final int ENCRYPTION_PGP = 1;
+ public static final int ENCRYPTION_OTR = 2;
+ public static final int ENCRYPTION_DECRYPTED = 3;
+
+ public static String CONVERSATION = "conversationUuid";
+ public static String COUNTERPART = "counterpart";
+ public static String BODY = "body";
+ public static String TIME_SENT = "timeSent";
+ public static String ENCRYPTION = "encryption";
+ public static String STATUS = "status";
+
+ protected String conversationUuid;
+ protected String counterpart;
+ protected String body;
+ protected long timeSent;
+ protected int encryption;
+ protected int status;
+ protected boolean read = true;
+
+ protected transient Conversation conversation = null;
+
+ public Message(Conversation conversation, String body, int encryption) {
+ this(java.util.UUID.randomUUID().toString(), conversation.getUuid(),
+ conversation.getContactJid(), body, System.currentTimeMillis(), encryption,
+ Message.STATUS_UNSEND);
+ this.conversation = conversation;
+ }
+
+ public Message(Conversation conversation, String counterpart, String body, int encryption, int status) {
+ this(java.util.UUID.randomUUID().toString(), conversation.getUuid(),counterpart, body, System.currentTimeMillis(), encryption,status);
+ this.conversation = conversation;
+ }
+
+ public Message(String uuid, String conversationUUid, String counterpart,
+ String body, long timeSent, int encryption, int status) {
+ this.uuid = uuid;
+ this.conversationUuid = conversationUUid;
+ this.counterpart = counterpart;
+ this.body = body;
+ this.timeSent = timeSent;
+ this.encryption = encryption;
+ this.status = status;
+ }
+
+ @Override
+ public ContentValues getContentValues() {
+ ContentValues values = new ContentValues();
+ values.put(UUID, uuid);
+ values.put(CONVERSATION, conversationUuid);
+ values.put(COUNTERPART, counterpart);
+ values.put(BODY, body);
+ values.put(TIME_SENT, timeSent);
+ values.put(ENCRYPTION, encryption);
+ values.put(STATUS, status);
+ return values;
+ }
+
+ public String getConversationUuid() {
+ return conversationUuid;
+ }
+
+ public Conversation getConversation() {
+ return this.conversation;
+ }
+
+ public String getCounterpart() {
+ return counterpart;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public long getTimeSent() {
+ return timeSent;
+ }
+
+ public int getEncryption() {
+ return encryption;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public static Message fromCursor(Cursor cursor) {
+ return new Message(cursor.getString(cursor.getColumnIndex(UUID)),
+ cursor.getString(cursor.getColumnIndex(CONVERSATION)),
+ cursor.getString(cursor.getColumnIndex(COUNTERPART)),
+ cursor.getString(cursor.getColumnIndex(BODY)),
+ cursor.getLong(cursor.getColumnIndex(TIME_SENT)),
+ cursor.getInt(cursor.getColumnIndex(ENCRYPTION)),
+ cursor.getInt(cursor.getColumnIndex(STATUS)));
+ }
+
+ public void setConversation(Conversation conv) {
+ this.conversation = conv;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public boolean isRead() {
+ return this.read;
+ }
+
+ public void markRead() {
+ this.read = true;
+ }
+
+ public void markUnread() {
+ this.read = false;
+ }
+
+ public void setTime(long time) {
+ this.timeSent = time;
+ }
+
+ public void setEncryption(int encryption) {
+ this.encryption = encryption;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+}
diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java
new file mode 100644
index 00000000..4a738e65
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/MucOptions.java
@@ -0,0 +1,5 @@
+package eu.siacs.conversations.entities;
+
+public class MucOptions {
+
+}
diff --git a/src/eu/siacs/conversations/entities/Presences.java b/src/eu/siacs/conversations/entities/Presences.java
new file mode 100644
index 00000000..af7926a8
--- /dev/null
+++ b/src/eu/siacs/conversations/entities/Presences.java
@@ -0,0 +1,76 @@
+package eu.siacs.conversations.entities;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class Presences {
+
+ public static final int CHAT = -1;
+ public static final int ONLINE = 0;
+ public static final int AWAY = 1;
+ public static final int XA = 2;
+ public static final int DND = 3;
+ public static final int OFFLINE = 4;
+
+ private Hashtable<String, Integer> presences = new Hashtable<String, Integer>();
+
+ public Hashtable<String, Integer> getPresences() {
+ return this.presences;
+ }
+
+ public void updatePresence(String resource, int status) {
+ this.presences.put(resource, status);
+ }
+
+ public void removePresence(String resource) {
+ this.presences.remove(resource);
+ }
+
+ public int getMostAvailableStatus() {
+ int status = OFFLINE;
+ Iterator<Entry<String, Integer>> it = presences.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, Integer> entry = it.next();
+ if (entry.getValue()<status) status = entry.getValue();
+ }
+ return status;
+ }
+
+ public String toJsonString() {
+ JSONArray json = new JSONArray();
+ Iterator<Entry<String, Integer>> it = presences.entrySet().iterator();
+
+ while (it.hasNext()) {
+ Entry<String, Integer> entry = it.next();
+ JSONObject jObj = new JSONObject();
+ try {
+ jObj.put("resource", entry.getKey());
+ jObj.put("status", entry.getValue());
+ } catch (JSONException e) {
+
+ }
+ json.put(jObj);
+ }
+ return json.toString();
+ }
+
+ public static Presences fromJsonString(String jsonString) {
+ Presences presences = new Presences();
+ try {
+ JSONArray json = new JSONArray(jsonString);
+ for (int i = 0; i < json.length(); ++i) {
+ JSONObject jObj = json.getJSONObject(i);
+ presences.updatePresence(jObj.getString("resource"),
+ jObj.getInt("status"));
+ }
+ } catch (JSONException e1) {
+
+ }
+ return presences;
+ }
+}