diff --git a/briar-core/src/org/briarproject/forum/ForumManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumManagerImpl.java index 534369d2d512c59bd214f5b3f39334836a80106a..d2b2d872e8ebd38954e273ae2a8579438638ba72 100644 --- a/briar-core/src/org/briarproject/forum/ForumManagerImpl.java +++ b/briar-core/src/org/briarproject/forum/ForumManagerImpl.java @@ -1,15 +1,12 @@ package org.briarproject.forum; import org.briarproject.api.FormatException; +import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.contact.Contact; import org.briarproject.api.data.BdfDictionary; -import org.briarproject.api.data.BdfReader; -import org.briarproject.api.data.BdfReaderFactory; -import org.briarproject.api.data.MetadataEncoder; -import org.briarproject.api.data.MetadataParser; +import org.briarproject.api.data.BdfList; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; -import org.briarproject.api.db.Metadata; import org.briarproject.api.db.Transaction; import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.ForumManager; @@ -24,8 +21,6 @@ import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; import org.briarproject.util.StringUtils; -import java.io.ByteArrayInputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -34,18 +29,12 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.logging.Logger; import javax.inject.Inject; -import static java.util.logging.Level.WARNING; -import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH; -import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH; -import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH; import static org.briarproject.api.identity.Author.Status.ANONYMOUS; import static org.briarproject.api.identity.Author.Status.UNKNOWN; import static org.briarproject.api.identity.Author.Status.VERIFIED; -import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; class ForumManagerImpl implements ForumManager { @@ -53,21 +42,13 @@ class ForumManagerImpl implements ForumManager { "859a7be50dca035b64bd6902fb797097" + "795af837abbf8c16d750b3c2ccc186ea")); - private static final Logger LOG = - Logger.getLogger(ForumManagerImpl.class.getName()); - private final DatabaseComponent db; - private final BdfReaderFactory bdfReaderFactory; - private final MetadataEncoder metadataEncoder; - private final MetadataParser metadataParser; + private final ClientHelper clientHelper; @Inject - ForumManagerImpl(DatabaseComponent db, BdfReaderFactory bdfReaderFactory, - MetadataEncoder metadataEncoder, MetadataParser metadataParser) { + ForumManagerImpl(DatabaseComponent db, ClientHelper clientHelper) { this.db = db; - this.bdfReaderFactory = bdfReaderFactory; - this.metadataEncoder = metadataEncoder; - this.metadataParser = metadataParser; + this.clientHelper = clientHelper; } @Override @@ -78,29 +59,21 @@ class ForumManagerImpl implements ForumManager { @Override public void addLocalPost(ForumPost p) throws DbException { try { - BdfDictionary d = new BdfDictionary(); - d.put("timestamp", p.getMessage().getTimestamp()); - if (p.getParent() != null) - d.put("parent", p.getParent().getBytes()); + BdfDictionary meta = new BdfDictionary(); + meta.put("timestamp", p.getMessage().getTimestamp()); + if (p.getParent() != null) meta.put("parent", p.getParent()); if (p.getAuthor() != null) { Author a = p.getAuthor(); - BdfDictionary d1 = new BdfDictionary(); - d1.put("id", a.getId().getBytes()); - d1.put("name", a.getName()); - d1.put("publicKey", a.getPublicKey()); - d.put("author", d1); - } - d.put("contentType", p.getContentType()); - d.put("local", true); - d.put("read", true); - Metadata meta = metadataEncoder.encode(d); - Transaction txn = db.startTransaction(); - try { - db.addLocalMessage(txn, p.getMessage(), CLIENT_ID, meta, true); - txn.setComplete(); - } finally { - db.endTransaction(txn); + BdfDictionary authorMeta = new BdfDictionary(); + authorMeta.put("id", a.getId()); + authorMeta.put("name", a.getName()); + authorMeta.put("publicKey", a.getPublicKey()); + meta.put("author", authorMeta); } + meta.put("contentType", p.getContentType()); + meta.put("local", true); + meta.put("read", true); + clientHelper.addLocalMessage(p.getMessage(), CLIENT_ID, meta, true); } catch (FormatException e) { throw new RuntimeException(e); } @@ -145,34 +118,11 @@ class ForumManagerImpl implements ForumManager { @Override public byte[] getPostBody(MessageId m) throws DbException { try { - byte[] raw; - Transaction txn = db.startTransaction(); - try { - raw = db.getRawMessage(txn, m); - txn.setComplete(); - } finally { - db.endTransaction(txn); - } - ByteArrayInputStream in = new ByteArrayInputStream(raw, - MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH); - BdfReader r = bdfReaderFactory.createReader(in); - r.readListStart(); - if (r.hasRaw()) r.skipRaw(); // Parent ID - else r.skipNull(); // No parent - if (r.hasList()) r.skipList(); // Author - else r.skipNull(); // No author - r.skipString(); // Content type - byte[] postBody = r.readRaw(MAX_FORUM_POST_BODY_LENGTH); - if (r.hasRaw()) r.skipRaw(); // Signature - else r.skipNull(); - r.readListEnd(); - if (!r.eof()) throw new FormatException(); - return postBody; + // Parent ID, author, content type, forum post body, signature + BdfList message = clientHelper.getMessageAsList(m); + return message.getRaw(3); } catch (FormatException e) { throw new DbException(e); - } catch (IOException e) { - // Shouldn't happen with ByteArrayInputStream - throw new RuntimeException(e); } } @@ -181,7 +131,7 @@ class ForumManagerImpl implements ForumManager { throws DbException { Set<AuthorId> localAuthorIds = new HashSet<AuthorId>(); Set<AuthorId> contactAuthorIds = new HashSet<AuthorId>(); - Map<MessageId, Metadata> metadata; + Map<MessageId, BdfDictionary> metadata; Transaction txn = db.startTransaction(); try { // Load the IDs of the user's identities @@ -191,20 +141,22 @@ class ForumManagerImpl implements ForumManager { for (Contact c : db.getContacts(txn)) contactAuthorIds.add(c.getAuthor().getId()); // Load the metadata - metadata = db.getMessageMetadata(txn, g); + metadata = clientHelper.getMessageMetadataAsDictionary(txn, g); txn.setComplete(); + } catch (FormatException e) { + throw new DbException(e); } finally { db.endTransaction(txn); } // Parse the metadata Collection<ForumPostHeader> headers = new ArrayList<ForumPostHeader>(); - for (Entry<MessageId, Metadata> e : metadata.entrySet()) { + for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) { try { - BdfDictionary d = metadataParser.parse(e.getValue()); - long timestamp = d.getLong("timestamp"); + BdfDictionary meta = entry.getValue(); + long timestamp = meta.getLong("timestamp"); Author author = null; Author.Status authorStatus = ANONYMOUS; - BdfDictionary d1 = d.getDictionary("author", null); + BdfDictionary d1 = meta.getDictionary("author", null); if (d1 != null) { AuthorId authorId = new AuthorId(d1.getRaw("id")); String name = d1.getString("name"); @@ -216,13 +168,12 @@ class ForumManagerImpl implements ForumManager { authorStatus = VERIFIED; else authorStatus = UNKNOWN; } - String contentType = d.getString("contentType"); - boolean read = d.getBoolean("read"); - headers.add(new ForumPostHeader(e.getKey(), timestamp, author, - authorStatus, contentType, read)); - } catch (FormatException ex) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, ex.toString(), ex); + String contentType = meta.getString("contentType"); + boolean read = meta.getBoolean("read"); + headers.add(new ForumPostHeader(entry.getKey(), timestamp, + author, authorStatus, contentType, read)); + } catch (FormatException e) { + throw new DbException(e); } } return headers; @@ -231,36 +182,18 @@ class ForumManagerImpl implements ForumManager { @Override public void setReadFlag(MessageId m, boolean read) throws DbException { try { - BdfDictionary d = new BdfDictionary(); - d.put("read", read); - Metadata meta = metadataEncoder.encode(d); - Transaction txn = db.startTransaction(); - try { - db.mergeMessageMetadata(txn, m, meta); - txn.setComplete(); - } finally { - db.endTransaction(txn); - } + BdfDictionary meta = new BdfDictionary(); + meta.put("read", read); + clientHelper.mergeMessageMetadata(m, meta); } catch (FormatException e) { throw new RuntimeException(e); } } private Forum parseForum(Group g) throws FormatException { - ByteArrayInputStream in = new ByteArrayInputStream(g.getDescriptor()); - BdfReader r = bdfReaderFactory.createReader(in); - try { - r.readListStart(); - String name = r.readString(MAX_FORUM_NAME_LENGTH); - byte[] salt = r.readRaw(FORUM_SALT_LENGTH); - r.readListEnd(); - if (!r.eof()) throw new FormatException(); - return new Forum(g, name, salt); - } catch (FormatException e) { - throw e; - } catch (IOException e) { - // Shouldn't happen with ByteArrayInputStream - throw new RuntimeException(e); - } + byte[] descriptor = g.getDescriptor(); + // Name, salt + BdfList forum = clientHelper.toList(descriptor, 0, descriptor.length); + return new Forum(g, forum.getString(0), forum.getRaw(1)); } } diff --git a/briar-core/src/org/briarproject/forum/ForumModule.java b/briar-core/src/org/briarproject/forum/ForumModule.java index 8442edeb7d7e6ba5615e1a05b887592a1c3e37fe..4a51872e7abc05aed8f2cdbfb59a6ecda10eca7d 100644 --- a/briar-core/src/org/briarproject/forum/ForumModule.java +++ b/briar-core/src/org/briarproject/forum/ForumModule.java @@ -35,10 +35,8 @@ public class ForumModule { @Provides @Singleton ForumManager provideForumManager(DatabaseComponent db, - ContactManager contactManager, BdfReaderFactory bdfReaderFactory, - MetadataEncoder metadataEncoder, MetadataParser metadataParser) { - return new ForumManagerImpl(db, bdfReaderFactory, metadataEncoder, - metadataParser); + ClientHelper clientHelper) { + return new ForumManagerImpl(db, clientHelper); } @Provides diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java index 657126053d82c6d490733cb12d4fa9410493ea4d..c1a0eb797cad84b3130b76785e1d397bb682dc32 100644 --- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java @@ -1,19 +1,16 @@ package org.briarproject.messaging; import org.briarproject.api.FormatException; +import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.PrivateGroupFactory; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager.AddContactHook; import org.briarproject.api.contact.ContactManager.RemoveContactHook; import org.briarproject.api.data.BdfDictionary; -import org.briarproject.api.data.BdfReader; -import org.briarproject.api.data.BdfReaderFactory; -import org.briarproject.api.data.MetadataEncoder; -import org.briarproject.api.data.MetadataParser; +import org.briarproject.api.data.BdfList; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; -import org.briarproject.api.db.Metadata; import org.briarproject.api.db.Transaction; import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessage; @@ -25,19 +22,12 @@ import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageStatus; import org.briarproject.util.StringUtils; -import java.io.ByteArrayInputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Map; -import java.util.logging.Logger; import javax.inject.Inject; -import static java.util.logging.Level.WARNING; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH; -import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; - class MessagingManagerImpl implements MessagingManager, AddContactHook, RemoveContactHook { @@ -45,25 +35,16 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, "6bcdc006c0910b0f44e40644c3b31f1a" + "8bf9a6d6021d40d219c86b731b903070")); - private static final Logger LOG = - Logger.getLogger(MessagingManagerImpl.class.getName()); - private final DatabaseComponent db; + private final ClientHelper clientHelper; private final PrivateGroupFactory privateGroupFactory; - private final BdfReaderFactory bdfReaderFactory; - private final MetadataEncoder metadataEncoder; - private final MetadataParser metadataParser; @Inject - MessagingManagerImpl(DatabaseComponent db, - PrivateGroupFactory privateGroupFactory, - BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder, - MetadataParser metadataParser) { + MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper, + PrivateGroupFactory privateGroupFactory) { this.db = db; + this.clientHelper = clientHelper; this.privateGroupFactory = privateGroupFactory; - this.bdfReaderFactory = bdfReaderFactory; - this.metadataEncoder = metadataEncoder; - this.metadataParser = metadataParser; } @Override @@ -77,7 +58,7 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, // Attach the contact ID to the group BdfDictionary d = new BdfDictionary(); d.put("contactId", c.getId().getInt()); - db.mergeGroupMetadata(txn, g.getId(), metadataEncoder.encode(d)); + clientHelper.mergeGroupMetadata(txn, g.getId(), d); } catch (FormatException e) { throw new RuntimeException(e); } @@ -100,21 +81,13 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, @Override public void addLocalMessage(PrivateMessage m) throws DbException { try { - BdfDictionary d = new BdfDictionary(); - d.put("timestamp", m.getMessage().getTimestamp()); - if (m.getParent() != null) - d.put("parent", m.getParent().getBytes()); - d.put("contentType", m.getContentType()); - d.put("local", true); - d.put("read", true); - Metadata meta = metadataEncoder.encode(d); - Transaction txn = db.startTransaction(); - try { - db.addLocalMessage(txn, m.getMessage(), CLIENT_ID, meta, true); - txn.setComplete(); - } finally { - db.endTransaction(txn); - } + BdfDictionary meta = new BdfDictionary(); + meta.put("timestamp", m.getMessage().getTimestamp()); + if (m.getParent() != null) meta.put("parent", m.getParent()); + meta.put("contentType", m.getContentType()); + meta.put("local", true); + meta.put("read", true); + clientHelper.addLocalMessage(m.getMessage(), CLIENT_ID, meta, true); } catch (FormatException e) { throw new RuntimeException(e); } @@ -123,16 +96,8 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, @Override public ContactId getContactId(GroupId g) throws DbException { try { - Metadata meta; - Transaction txn = db.startTransaction(); - try { - meta = db.getGroupMetadata(txn, g); - txn.setComplete(); - } finally { - db.endTransaction(txn); - } - BdfDictionary d = metadataParser.parse(meta); - return new ContactId(d.getLong("contactId").intValue()); + BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(g); + return new ContactId(meta.getLong("contactId").intValue()); } catch (FormatException e) { throw new DbException(e); } @@ -154,14 +119,16 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, @Override public Collection<PrivateMessageHeader> getMessageHeaders(ContactId c) throws DbException { - Map<MessageId, Metadata> metadata; + Map<MessageId, BdfDictionary> metadata; Collection<MessageStatus> statuses; Transaction txn = db.startTransaction(); try { GroupId g = getContactGroup(db.getContact(txn, c)).getId(); - metadata = db.getMessageMetadata(txn, g); + metadata = clientHelper.getMessageMetadataAsDictionary(txn, g); statuses = db.getMessageStatus(txn, c, g); txn.setComplete(); + } catch (FormatException e) { + throw new DbException(e); } finally { db.endTransaction(txn); } @@ -169,18 +136,17 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, new ArrayList<PrivateMessageHeader>(); for (MessageStatus s : statuses) { MessageId id = s.getMessageId(); - Metadata m = metadata.get(id); - if (m == null) continue; + BdfDictionary meta = metadata.get(id); + if (meta == null) continue; try { - BdfDictionary d = metadataParser.parse(m); - long timestamp = d.getLong("timestamp"); - String contentType = d.getString("contentType"); - boolean local = d.getBoolean("local"); - boolean read = d.getBoolean("read"); + long timestamp = meta.getLong("timestamp"); + String contentType = meta.getString("contentType"); + boolean local = meta.getBoolean("local"); + boolean read = meta.getBoolean("read"); headers.add(new PrivateMessageHeader(id, timestamp, contentType, local, read, s.isSent(), s.isSeen())); } catch (FormatException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + throw new DbException(e); } } return headers; @@ -188,47 +154,21 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook, @Override public byte[] getMessageBody(MessageId m) throws DbException { - byte[] raw; - Transaction txn = db.startTransaction(); try { - raw = db.getRawMessage(txn, m); - txn.setComplete(); - } finally { - db.endTransaction(txn); - } - ByteArrayInputStream in = new ByteArrayInputStream(raw, - MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH); - BdfReader r = bdfReaderFactory.createReader(in); - try { - r.readListStart(); - if (r.hasRaw()) r.skipRaw(); // Parent ID - else r.skipNull(); // No parent - r.skipString(); // Content type - byte[] messageBody = r.readRaw(MAX_PRIVATE_MESSAGE_BODY_LENGTH); - r.readListEnd(); - if (!r.eof()) throw new FormatException(); - return messageBody; + // Parent ID, content type, private message body + BdfList message = clientHelper.getMessageAsList(m); + return message.getRaw(2); } catch (FormatException e) { throw new DbException(e); - } catch (IOException e) { - // Shouldn't happen with ByteArrayInputStream - throw new RuntimeException(e); } } @Override public void setReadFlag(MessageId m, boolean read) throws DbException { try { - BdfDictionary d = new BdfDictionary(); - d.put("read", read); - Metadata meta = metadataEncoder.encode(d); - Transaction txn = db.startTransaction(); - try { - db.mergeMessageMetadata(txn, m, meta); - txn.setComplete(); - } finally { - db.endTransaction(txn); - } + BdfDictionary meta = new BdfDictionary(); + meta.put("read", read); + clientHelper.mergeMessageMetadata(m, meta); } catch (FormatException e) { throw new RuntimeException(e); } diff --git a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java index 6bf9b5281f660432cd5c4af00fd251de9030d43a..2c90166526ae97810aca79d0e1d8d6cddb1e4e1e 100644 --- a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java +++ b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java @@ -3,21 +3,16 @@ package org.briarproject.properties; import org.briarproject.api.DeviceId; import org.briarproject.api.FormatException; import org.briarproject.api.TransportId; +import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.PrivateGroupFactory; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager.AddContactHook; import org.briarproject.api.contact.ContactManager.RemoveContactHook; import org.briarproject.api.data.BdfDictionary; -import org.briarproject.api.data.BdfReader; -import org.briarproject.api.data.BdfReaderFactory; -import org.briarproject.api.data.BdfWriter; -import org.briarproject.api.data.BdfWriterFactory; -import org.briarproject.api.data.MetadataEncoder; -import org.briarproject.api.data.MetadataParser; +import org.briarproject.api.data.BdfList; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; -import org.briarproject.api.db.Metadata; import org.briarproject.api.db.NoSuchGroupException; import org.briarproject.api.db.Transaction; import org.briarproject.api.properties.TransportProperties; @@ -27,14 +22,10 @@ import org.briarproject.api.sync.Group; import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.Message; -import org.briarproject.api.sync.MessageFactory; import org.briarproject.api.sync.MessageId; import org.briarproject.api.system.Clock; import org.briarproject.util.StringUtils; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -42,9 +33,6 @@ import java.util.Map.Entry; import javax.inject.Inject; -import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH; -import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; - class TransportPropertyManagerImpl implements TransportPropertyManager, AddContactHook, RemoveContactHook { @@ -55,28 +43,18 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0]; private final DatabaseComponent db; + private final ClientHelper clientHelper; private final PrivateGroupFactory privateGroupFactory; - private final MessageFactory messageFactory; - private final BdfReaderFactory bdfReaderFactory; - private final BdfWriterFactory bdfWriterFactory; - private final MetadataEncoder metadataEncoder; - private final MetadataParser metadataParser; private final Clock clock; private final Group localGroup; @Inject TransportPropertyManagerImpl(DatabaseComponent db, - GroupFactory groupFactory, PrivateGroupFactory privateGroupFactory, - MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory, - BdfWriterFactory bdfWriterFactory, MetadataEncoder metadataEncoder, - MetadataParser metadataParser, Clock clock) { + ClientHelper clientHelper, GroupFactory groupFactory, + PrivateGroupFactory privateGroupFactory, Clock clock) { this.db = db; + this.clientHelper = clientHelper; this.privateGroupFactory = privateGroupFactory; - this.messageFactory = messageFactory; - this.bdfReaderFactory = bdfReaderFactory; - this.bdfWriterFactory = bdfWriterFactory; - this.metadataEncoder = metadataEncoder; - this.metadataParser = metadataParser; this.clock = clock; localGroup = groupFactory.createGroup(CLIENT_ID, LOCAL_GROUP_DESCRIPTOR); @@ -145,8 +123,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, true); if (latest != null) { // Retrieve and parse the latest local properties - byte[] raw = db.getRawMessage(txn, latest.messageId); - p = parseProperties(raw); + BdfList message = clientHelper.getMessageAsList(txn, + latest.messageId); + p = parseProperties(message); } txn.setComplete(); } finally { @@ -175,8 +154,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, LatestUpdate latest = findLatest(txn, g.getId(), t, false); if (latest != null) { // Retrieve and parse the latest remote properties - byte[] raw = db.getRawMessage(txn, latest.messageId); - remote.put(c.getId(), parseProperties(raw)); + BdfList message = clientHelper.getMessageAsList(txn, + latest.messageId); + remote.put(c.getId(), parseProperties(message)); } } txn.setComplete(); @@ -206,8 +186,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, merged = p; changed = true; } else { - byte[] raw = db.getRawMessage(txn, latest.messageId); - TransportProperties old = parseProperties(raw); + BdfList message = clientHelper.getMessageAsList(txn, + latest.messageId); + TransportProperties old = parseProperties(message); merged = new TransportProperties(old); merged.putAll(p); changed = !merged.equals(old); @@ -250,8 +231,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, localGroup.getId(), true); // Retrieve and parse the latest local properties for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) { - byte[] raw = db.getRawMessage(txn, e.getValue().messageId); - local.put(e.getKey(), parseProperties(raw)); + BdfList message = clientHelper.getMessageAsList(txn, + e.getValue().messageId); + local.put(e.getKey(), parseProperties(message)); } return local; } catch (NoSuchGroupException e) { @@ -266,48 +248,35 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, TransportId t, TransportProperties p, long version, boolean local, boolean shared) throws DbException { try { - byte[] body = encodeProperties(dev, t, p, version); + BdfList body = encodeProperties(dev, t, p, version); long now = clock.currentTimeMillis(); - Message m = messageFactory.createMessage(g, now, body); - BdfDictionary d = new BdfDictionary(); - d.put("transportId", t.getString()); - d.put("version", version); - d.put("local", local); - Metadata meta = metadataEncoder.encode(d); - db.addLocalMessage(txn, m, CLIENT_ID, meta, shared); + Message m = clientHelper.createMessage(g, now, body); + BdfDictionary meta = new BdfDictionary(); + meta.put("transportId", t.getString()); + meta.put("version", version); + meta.put("local", local); + clientHelper.addLocalMessage(txn, m, CLIENT_ID, meta, shared); } catch (FormatException e) { throw new RuntimeException(e); } } - private byte[] encodeProperties(DeviceId dev, TransportId t, + private BdfList encodeProperties(DeviceId dev, TransportId t, TransportProperties p, long version) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - BdfWriter w = bdfWriterFactory.createWriter(out); - try { - w.writeListStart(); - w.writeRaw(dev.getBytes()); - w.writeString(t.getString()); - w.writeLong(version); - w.writeDictionary(p); - w.writeListEnd(); - } catch (IOException e) { - // Shouldn't happen with ByteArrayOutputStream - throw new RuntimeException(e); - } - return out.toByteArray(); + return BdfList.of(dev, t.getString(), version, p); } private Map<TransportId, LatestUpdate> findLatest(Transaction txn, GroupId g, boolean local) throws DbException, FormatException { Map<TransportId, LatestUpdate> latestUpdates = new HashMap<TransportId, LatestUpdate>(); - Map<MessageId, Metadata> metadata = db.getMessageMetadata(txn, g); - for (Entry<MessageId, Metadata> e : metadata.entrySet()) { - BdfDictionary d = metadataParser.parse(e.getValue()); - if (d.getBoolean("local") == local) { - TransportId t = new TransportId(d.getString("transportId")); - long version = d.getLong("version"); + Map<MessageId, BdfDictionary> metadata = + clientHelper.getMessageMetadataAsDictionary(txn, g); + for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) { + BdfDictionary meta = e.getValue(); + if (meta.getBoolean("local") == local) { + TransportId t = new TransportId(meta.getString("transportId")); + long version = meta.getLong("version"); LatestUpdate latest = latestUpdates.get(t); if (latest == null || version > latest.version) latestUpdates.put(t, new LatestUpdate(e.getKey(), version)); @@ -319,12 +288,13 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, private LatestUpdate findLatest(Transaction txn, GroupId g, TransportId t, boolean local) throws DbException, FormatException { LatestUpdate latest = null; - Map<MessageId, Metadata> metadata = db.getMessageMetadata(txn, g); - for (Entry<MessageId, Metadata> e : metadata.entrySet()) { - BdfDictionary d = metadataParser.parse(e.getValue()); - if (d.getString("transportId").equals(t.getString()) - && d.getBoolean("local") == local) { - long version = d.getLong("version"); + Map<MessageId, BdfDictionary> metadata = + clientHelper.getMessageMetadataAsDictionary(txn, g); + for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) { + BdfDictionary meta = e.getValue(); + if (meta.getString("transportId").equals(t.getString()) + && meta.getBoolean("local") == local) { + long version = meta.getLong("version"); if (latest == null || version > latest.version) latest = new LatestUpdate(e.getKey(), version); } @@ -332,33 +302,14 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, return latest; } - private TransportProperties parseProperties(byte[] raw) + private TransportProperties parseProperties(BdfList message) throws FormatException { + // Device ID, transport ID, version, properties + BdfDictionary dictionary = message.getDictionary(3); TransportProperties p = new TransportProperties(); - ByteArrayInputStream in = new ByteArrayInputStream(raw, - MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH); - BdfReader r = bdfReaderFactory.createReader(in); - try { - r.readListStart(); - r.skipRaw(); // Device ID - r.skipString(); // Transport ID - r.skipLong(); // Version - r.readDictionaryStart(); - while (!r.hasDictionaryEnd()) { - String key = r.readString(MAX_PROPERTY_LENGTH); - String value = r.readString(MAX_PROPERTY_LENGTH); - p.put(key, value); - } - r.readDictionaryEnd(); - r.readListEnd(); - if (!r.eof()) throw new FormatException(); - return p; - } catch (FormatException e) { - throw e; - } catch (IOException e) { - // Shouldn't happen with ByteArrayInputStream - throw new RuntimeException(e); - } + for (String key : dictionary.keySet()) + p.put(key, dictionary.getString(key)); + return p; } private static class LatestUpdate {