http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java ---------------------------------------------------------------------- diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java index 568db73..f0a7027 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java @@ -19,12 +19,13 @@ package org.apache.james.mailbox.cassandra.mail; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.assertj.guava.api.Assertions.assertThat; import java.util.stream.LongStream; import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.init.CassandraModuleComposite; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.cassandra.modules.CassandraAclModule; import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule; import org.apache.james.mailbox.cassandra.modules.CassandraUidModule; @@ -35,6 +36,7 @@ import org.junit.Before; import org.junit.Test; import com.github.fge.lambdas.Throwing; +import com.google.common.base.Optional; public class CassandraUidProviderTest { @@ -67,12 +69,12 @@ public class CassandraUidProviderTest { @Test public void lastUidShouldRetrieveValueStoredByNextUid() throws Exception { int nbEntries = 100; - long result = uidProvider.lastUid(null, mailbox); - assertEquals(0, result); + Optional<MessageUid> result = uidProvider.lastUid(null, mailbox); + assertThat(result).isAbsent(); LongStream.range(0, nbEntries) .forEach(Throwing.longConsumer(value -> { - long uid = uidProvider.nextUid(null, mailbox); - assertThat(uid).isEqualTo(uidProvider.lastUid(null, mailbox)); + MessageUid uid = uidProvider.nextUid(null, mailbox); + assertThat(uid).isEqualTo(uidProvider.lastUid(null, mailbox).get()); }) ); } @@ -80,11 +82,10 @@ public class CassandraUidProviderTest { @Test public void nextUidShouldIncrementValueByOne() throws Exception { int nbEntries = 100; - long lastUid = uidProvider.lastUid(null, mailbox); - LongStream.range(lastUid + 1, lastUid + nbEntries) + LongStream.range(1, nbEntries) .forEach(Throwing.longConsumer(value -> { - long result = uidProvider.nextUid(null, mailbox); - assertThat(value).isEqualTo(result); + MessageUid result = uidProvider.nextUid(null, mailbox); + assertThat(value).isEqualTo(result.asLong()); }) ); } @@ -94,7 +95,8 @@ public class CassandraUidProviderTest { int nbEntries = 100; long nbValues = LongStream.range(0, nbEntries) .parallel() - .map(Throwing.longUnaryOperator(x -> uidProvider.nextUid(null, mailbox))) + .mapToObj(x -> x) + .map(Throwing.function(x -> uidProvider.nextUid(null, mailbox))) .distinct() .count(); assertThat(nbValues).isEqualTo(nbEntries);
http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java index 5d24222..c5b1c8d 100644 --- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java +++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java @@ -31,6 +31,7 @@ import javax.inject.Inject; import org.apache.james.mailbox.MailboxManager.SearchCapabilities; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer; import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants; import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson; @@ -80,7 +81,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe } @Override - public Iterator<Long> search(MailboxSession session, Mailbox mailbox, SearchQuery searchQuery) throws MailboxException { + public Iterator<MessageUid> search(MailboxSession session, Mailbox mailbox, SearchQuery searchQuery) throws MailboxException { Preconditions.checkArgument(session != null, "'session' is mandatory"); MailboxId mailboxId = mailbox.getMailboxId(); MultimailboxesSearchQuery query = MultimailboxesSearchQuery.from(searchQuery).inMailboxes(mailboxId).build(); @@ -91,7 +92,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe } @Override - public Map<MailboxId, Collection<Long>> search(MailboxSession session, MultimailboxesSearchQuery searchQuery) + public Map<MailboxId, Collection<MessageUid>> search(MailboxSession session, MultimailboxesSearchQuery searchQuery) throws MailboxException { Preconditions.checkArgument(session != null, "'session' is mandatory"); return searcher.search(ImmutableList.of(session.getUser()), searchQuery).asMap(); @@ -107,7 +108,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe } @Override - public void delete(MailboxSession session, Mailbox mailbox, List<Long> expungedUids) throws MailboxException { + public void delete(MailboxSession session, Mailbox mailbox, List<MessageUid> expungedUids) throws MailboxException { try { indexer.deleteMessages(expungedUids.stream() .map(uid -> indexIdFor(mailbox, uid)) @@ -152,7 +153,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe } } - private String indexIdFor(Mailbox mailbox, long messageId) { + private String indexIdFor(Mailbox mailbox, MessageUid messageId) { return String.join(ID_SEPARATOR, mailbox.getMailboxId().serialize(), String.valueOf(messageId)); } http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java index f67e5d1..b474c1b 100644 --- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java +++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.james.mailbox.MailboxSession.User; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.elasticsearch.query.DateResolutionFormater; import org.apache.james.mailbox.extractor.TextExtractor; import org.apache.james.mailbox.store.mail.model.MailboxMessage; @@ -118,7 +119,7 @@ public class IndexableMessage { .collect(Collectors.joining(" ")); } - private Long id; + private MessageUid id; private String mailboxId; private List<String> users; private long modSeq; @@ -149,7 +150,7 @@ public class IndexableMessage { @JsonProperty(JsonMessageConstants.ID) public Long getId() { - return id; + return id.asLong(); } @JsonProperty(JsonMessageConstants.MAILBOX_ID) http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java index 10a1ca4..180bf99 100644 --- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java +++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java @@ -228,10 +228,10 @@ public class CriterionConverter { .map(this::uidRangeFilter), BoolQueryBuilder::should)); } - private QueryBuilder uidRangeFilter(SearchQuery.NumericRange numericRange) { + private QueryBuilder uidRangeFilter(SearchQuery.UidRange numericRange) { return rangeQuery(JsonMessageConstants.ID) - .lte(numericRange.getHighValue()) - .gte(numericRange.getLowValue()); + .lte(numericRange.getHighValue().asLong()) + .gte(numericRange.getLowValue().asLong()); } private QueryBuilder convertHeader(SearchQuery.HeaderCriterion headerCriterion) { http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java index 2eb4cf1..3b2c012 100644 --- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java +++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java @@ -28,6 +28,7 @@ import javax.inject.Inject; import org.apache.commons.lang3.tuple.Pair; import org.apache.james.mailbox.MailboxSession.User; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer; import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants; import org.apache.james.mailbox.elasticsearch.query.QueryConverter; @@ -71,7 +72,7 @@ public class ElasticSearchSearcher { this.mailboxIdFactory = mailboxIdFactory; } - public Multimap<MailboxId, Long> search(List<User> users, MultimailboxesSearchQuery query) throws MailboxException { + public Multimap<MailboxId, MessageUid> search(List<User> users, MultimailboxesSearchQuery query) throws MailboxException { return new ScrollIterable(client, getSearchRequestBuilder(client, users, query)).stream() .flatMap(this::transformResponseToUidStream) .collect(Guavate.toImmutableListMultimap(Pair::getLeft, Pair::getRight)); @@ -91,19 +92,19 @@ public class ElasticSearchSearcher { (partialResult1, partialResult2) -> partialResult1); } - private Stream<Pair<MailboxId, Long>> transformResponseToUidStream(SearchResponse searchResponse) { + private Stream<Pair<MailboxId, MessageUid>> transformResponseToUidStream(SearchResponse searchResponse) { return StreamSupport.stream(searchResponse.getHits().spliterator(), false) .map(this::extractContentFromHit) .filter(Optional::isPresent) .map(Optional::get); } - private Optional<Pair<MailboxId, Long>> extractContentFromHit(SearchHit hit) { + private Optional<Pair<MailboxId, MessageUid>> extractContentFromHit(SearchHit hit) { SearchHitField mailboxId = hit.field(JsonMessageConstants.MAILBOX_ID); SearchHitField uid = hit.field(JsonMessageConstants.ID); if (mailboxId != null && uid != null) { Number uidAsNumber = uid.getValue(); - return Optional.of(Pair.of(mailboxIdFactory.fromString(mailboxId.getValue()), uidAsNumber.longValue())); + return Optional.of(Pair.of(mailboxIdFactory.fromString(mailboxId.getValue()), MessageUid.of(uidAsNumber.longValue()))); } else { LOGGER.warn("Can not extract UID and/or MailboxId for search result " + hit.getId()); return Optional.empty(); http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java index 639eeb5..05b39df 100644 --- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java +++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java @@ -32,6 +32,7 @@ import java.util.List; import javax.mail.Flags; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.MailboxSession.User; import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer; import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson; @@ -86,7 +87,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { .andReturn(user); Mailbox mailbox = control.createMock(Mailbox.class); - long messageId = 1; + MessageUid messageId = MessageUid.of(1); TestId mailboxId = TestId.of(12); expect(mailbox.getMailboxId()).andReturn(mailboxId); MailboxMessage message = mockedMessage(messageId); @@ -100,7 +101,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { control.verify(); } - private MailboxMessage mockedMessage(long messageId) throws IOException { + private MailboxMessage mockedMessage(MessageUid messageId) throws IOException { MailboxMessage message = control.createMock(MailboxMessage.class); expect(message.getUid()).andReturn(messageId).anyTimes(); return message; @@ -115,7 +116,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { Mailbox mailbox = control.createMock(Mailbox.class); - long messageId = 1; + MessageUid messageId = MessageUid.of(1); TestId mailboxId = TestId.of(12); MailboxMessage message = mockedMessage(messageId); expect(mailbox.getMailboxId()).andReturn(mailboxId); @@ -133,7 +134,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { public void deleteShouldWork() throws Exception { MailboxSession session = control.createMock(MailboxSession.class); Mailbox mailbox = control.createMock(Mailbox.class); - long messageId = 1; + MessageUid messageId = MessageUid.of(1); TestId mailboxId = TestId.of(12); expect(mailbox.getMailboxId()).andReturn(mailboxId); @@ -151,11 +152,11 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { public void deleteShouldWorkWhenMultipleMessageIds() throws Exception { MailboxSession session = control.createMock(MailboxSession.class); Mailbox mailbox = control.createMock(Mailbox.class); - long messageId1 = 1; - long messageId2 = 2; - long messageId3 = 3; - long messageId4 = 4; - long messageId5 = 5; + MessageUid messageId1 = MessageUid.of(1); + MessageUid messageId2 = MessageUid.of(2); + MessageUid messageId3 = MessageUid.of(3); + MessageUid messageId4 = MessageUid.of(4); + MessageUid messageId5 = MessageUid.of(5); TestId mailboxId = TestId.of(12); expect(mailbox.getMailboxId()).andReturn(mailboxId).times(5); @@ -173,7 +174,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { public void deleteShouldNotPropagateExceptionWhenExceptionOccurs() throws Exception { MailboxSession session = control.createMock(MailboxSession.class); Mailbox mailbox = control.createMock(Mailbox.class); - long messageId = 1; + MessageUid messageId = MessageUid.of(1); TestId mailboxId = TestId.of(12); expect(mailbox.getMailboxId()).andReturn(mailboxId).times(2); @@ -193,7 +194,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { Mailbox mailbox = control.createMock(Mailbox.class); Flags flags = new Flags(); - long messageId = 1; + MessageUid messageId = MessageUid.of(1); UpdatedFlags updatedFlags = new UpdatedFlags(messageId, MODSEQ, flags, flags); TestId mailboxId = TestId.of(12); @@ -216,7 +217,7 @@ public class ElasticSearchListeningMailboxMessageSearchIndexTest { Mailbox mailbox = control.createMock(Mailbox.class); Flags flags = new Flags(); - long messageId = 1; + MessageUid messageId = MessageUid.of(1); UpdatedFlags updatedFlags = new UpdatedFlags(messageId, MODSEQ, flags, flags); TestId mailboxId = TestId.of(12); http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java ---------------------------------------------------------------------- diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java index ce43184..fa13685 100644 --- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java +++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java @@ -35,6 +35,7 @@ import javax.mail.util.SharedByteArrayInputStream; import org.apache.commons.io.IOUtils; import org.apache.james.mailbox.FlagsBuilder; import org.apache.james.mailbox.MailboxSession.User; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.mock.MockMailboxSession; import org.apache.james.mailbox.store.TestId; import org.apache.james.mailbox.store.extractor.DefaultTextExtractor; @@ -55,7 +56,7 @@ public class MailboxMessageToElasticSearchJsonTest { public static final int BODY_START_OCTET = 100; public static final TestId MAILBOX_ID = TestId.of(18L); public static final long MOD_SEQ = 42L; - public static final long UID = 25L; + public static final MessageUid UID = MessageUid.of(25); public static final Charset CHARSET = Charsets.UTF_8; private Date date; @@ -102,6 +103,7 @@ public class MailboxMessageToElasticSearchJsonTest { new Flags(), propertyBuilder, MAILBOX_ID); + spamMail.setUid(UID); spamMail.setModSeq(MOD_SEQ); assertThatJson(messageToElasticSearchJson.convertToJson(spamMail, ImmutableList.of(new MockMailboxSession("username").getUser()))) .when(IGNORING_ARRAY_ORDER) @@ -265,6 +267,7 @@ public class MailboxMessageToElasticSearchJsonTest { new Flags(), propertyBuilder, MAILBOX_ID); + spamMail.setUid(UID); spamMail.setModSeq(MOD_SEQ); assertThatJson(messageToElasticSearchJson.convertToJson(spamMail, ImmutableList.of(new MockMailboxSession("username").getUser()))) .when(IGNORING_ARRAY_ORDER) http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java index b6d7e35..982f035 100644 --- a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java +++ b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java @@ -69,6 +69,7 @@ import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.hbase.io.ChunkInputStream; import org.apache.james.mailbox.hbase.mail.HBaseMailboxMessage; import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox; @@ -215,20 +216,32 @@ public class HBaseUtils { * @param uid message uid * @return rowkey byte array that can be used with HBase API */ - public static byte[] messageRowKey(HBaseId mailboxUid, long uid) { + public static byte[] messageRowKey(HBaseId mailboxUid, MessageUid uid) { /** message uid's are stored in reverse order so we will always have the most recent messages first*/ - return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(Long.MAX_VALUE - uid)); + return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(Long.MAX_VALUE - uid.asLong())); } /** + * Utility method to build row key min limit from mailbox UUID. + * The message uid's are stored in reverse order by substracting the uid value + * from Long.MAX_VALUE. + * @param mailboxUid mailbox UUID + * @return rowkey byte array that can be used with HBase API + */ + public static byte[] minMessageRowKey(HBaseId mailboxUid) { + return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(Long.MAX_VALUE)); + } + + + /** * Utility to build row keys from mailboxUID and a value. The value is added to * the key without any other operations. * @param mailboxUid mailbox HBaseId * @param value * @return rowkey byte array that can be used with HBase API */ - public static byte[] customMessageRowKey(HBaseId mailboxUid, long value) { - return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(value)); + public static byte[] customMessageRowKey(HBaseId mailboxUid, MessageUid value) { + return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(value.asLong())); } /** @@ -246,7 +259,12 @@ public class HBaseUtils { List<Property> propList = new ArrayList<Property>(); KeyValue[] keys = result.raw(); String mediaType = null, subType = null; - Long modSeq = null, uid, bodyOctets = null, contentOctets = null, textualLineCount = null; + MessageUid uid; + Long modSeq = null; + Long bodyOctets = null; + Long contentOctets = null; + Long textualLineCount = null; + Date internalDate = null; int i = 0; @@ -301,7 +319,7 @@ public class HBaseUtils { i++; } HBaseId uuid = HBaseIdFromRowKey(result.getRow()); - uid = Long.MAX_VALUE - Bytes.toLong(result.getRow(), 16); + uid = MessageUid.of(Long.MAX_VALUE - Bytes.toLong(result.getRow(), 16)); PropertyBuilder props = new PropertyBuilder(propList); props.setMediaType(mediaType); props.setSubType(subType); http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java index 6ff9cd1..5c3bec9 100644 --- a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java +++ b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java @@ -28,6 +28,7 @@ import java.io.InputStream; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.Date; import java.util.List; @@ -35,6 +36,7 @@ import javax.mail.Flags; import org.apache.commons.lang.NotImplementedException; import org.apache.hadoop.conf.Configuration; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.hbase.HBaseId; import org.apache.james.mailbox.hbase.io.ChunkInputStream; @@ -44,8 +46,10 @@ import org.apache.james.mailbox.store.mail.model.FlagsBuilder; import org.apache.james.mailbox.store.mail.model.MailboxMessage; import org.apache.james.mailbox.store.mail.model.MessageId; import org.apache.james.mailbox.store.mail.model.Property; -import org.apache.james.mailbox.store.mail.model.impl.MessageUidComparator; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; +import org.apache.james.mailbox.store.search.comparator.UidComparator; + +import com.google.common.base.Objects; /** * Concrete HBaseMailboxMessage implementation. This implementation does not store any @@ -54,14 +58,14 @@ import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; */ public class HBaseMailboxMessage implements MailboxMessage { - private static final MessageUidComparator MESSAGE_UID_COMPARATOR = new MessageUidComparator(); + private static final Comparator<MailboxMessage> MESSAGE_UID_COMPARATOR = new UidComparator(); private static final String TOSTRING_SEPARATOR = " "; /** Configuration for the HBase cluster */ private final Configuration conf; /** The value for the mailboxId field */ private final HBaseId mailboxId; /** The value for the uid field */ - private long uid; + private MessageUid uid; /** The value for the modSeq field */ private long modSeq; /** The value for the internalDate field */ @@ -96,7 +100,7 @@ public class HBaseMailboxMessage implements MailboxMessage { * Create a copy of the given message. * All properties are cloned except mailbox and UID. */ - public HBaseMailboxMessage(Configuration conf, HBaseId mailboxId, long uid, long modSeq, MailboxMessage original) throws MailboxException { + public HBaseMailboxMessage(Configuration conf, HBaseId mailboxId, MessageUid uid, long modSeq, MailboxMessage original) throws MailboxException { this.conf = conf; this.mailboxId = mailboxId; this.uid = uid; @@ -151,38 +155,17 @@ public class HBaseMailboxMessage implements MailboxMessage { @Override public int hashCode() { - final int PRIME = 31; - int result = 1; - result = PRIME * result + mailboxId.hashCode(); - result = PRIME * result + (int) (uid ^ (uid >>> 32)); - return result; + return Objects.hashCode(mailboxId, uid); } @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final HBaseMailboxMessage other = (HBaseMailboxMessage) obj; - if (getMailboxId() != null) { - if (!getMailboxId().equals(other.getMailboxId())) { - return false; - } - } else { - if (other.getMailboxId() != null) { - return false; - } - } - if (uid != other.uid) { - return false; + if (obj instanceof HBaseMailboxMessage) { + HBaseMailboxMessage other = (HBaseMailboxMessage) obj; + return Objects.equal(this.mailboxId, other.mailboxId) && + Objects.equal(this.uid, other.uid) ; } - return true; + return false; } @Override @@ -266,7 +249,7 @@ public class HBaseMailboxMessage implements MailboxMessage { } @Override - public long getUid() { + public MessageUid getUid() { return uid; } @@ -301,7 +284,7 @@ public class HBaseMailboxMessage implements MailboxMessage { } @Override - public void setUid(long uid) { + public void setUid(MessageUid uid) { this.uid = uid; } http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java index 1b9e70b..713f3a3 100644 --- a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java +++ b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java @@ -33,11 +33,11 @@ import static org.apache.james.mailbox.hbase.HBaseNames.MESSAGES_TABLE; import static org.apache.james.mailbox.hbase.HBaseNames.MESSAGE_DATA_BODY_CF; import static org.apache.james.mailbox.hbase.HBaseNames.MESSAGE_DATA_HEADERS_CF; import static org.apache.james.mailbox.hbase.HBaseNames.MESSAGE_MODSEQ; -import static org.apache.james.mailbox.hbase.HBaseUtils.customMessageRowKey; import static org.apache.james.mailbox.hbase.HBaseUtils.flagsToPut; import static org.apache.james.mailbox.hbase.HBaseUtils.messageMetaFromResult; import static org.apache.james.mailbox.hbase.HBaseUtils.messageRowKey; import static org.apache.james.mailbox.hbase.HBaseUtils.metadataToPut; +import static org.apache.james.mailbox.hbase.HBaseUtils.minMessageRowKey; import java.io.BufferedInputStream; import java.io.IOException; @@ -64,6 +64,7 @@ import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter; import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; import org.apache.hadoop.hbase.util.Bytes; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.hbase.HBaseId; import org.apache.james.mailbox.hbase.io.ChunkOutputStream; @@ -80,6 +81,9 @@ import org.apache.james.mailbox.store.mail.model.Mailbox; import org.apache.james.mailbox.store.mail.model.MailboxMessage; import org.apache.james.mailbox.store.transaction.NonTransactionalMapper; +import com.google.common.base.Optional; +import com.google.common.collect.Iterables; + /** * HBase implementation of a {@link MessageMapper}. * I don't know if this class is thread-safe! Asume it is not! @@ -110,8 +114,8 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag HBaseId mailboxId = (HBaseId) mailbox.getMailboxId(); try { List<MailboxMessage> results; - long from = set.getUidFrom(); - final long to = set.getUidTo(); + MessageUid from = set.getUidFrom(); + final MessageUid to = set.getUidTo(); final Type type = set.getType(); switch (type) { @@ -139,7 +143,7 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag private List<MailboxMessage> findMessagesInMailbox(HBaseId mailboxId, int batchSize, boolean flaggedForDelete) throws IOException { List<MailboxMessage> messageList = new ArrayList<MailboxMessage>(); HTable messages = new HTable(conf, MESSAGES_TABLE); - Scan scan = new Scan(customMessageRowKey(mailboxId, 0L), + Scan scan = new Scan(minMessageRowKey(mailboxId), new PrefixFilter(mailboxId.toBytes())); if (flaggedForDelete) { SingleColumnValueFilter filter = new SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, MARKER_PRESENT); @@ -165,10 +169,10 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag return messageList; } - private List<MailboxMessage> findMessagesInMailboxWithUID(HBaseId mailboxId, long messageUid, boolean flaggedForDelete) throws IOException { + private List<MailboxMessage> findMessagesInMailboxWithUID(HBaseId mailboxId, MessageUid from, boolean flaggedForDelete) throws IOException { List<MailboxMessage> messageList = new ArrayList<MailboxMessage>(); HTable messages = new HTable(conf, MESSAGES_TABLE); - Get get = new Get(messageRowKey(mailboxId, messageUid)); + Get get = new Get(messageRowKey(mailboxId, from)); get.setMaxVersions(1); /* we exclude the message content column family because it could be too large. * the content will be pulled from HBase on demand by using a a ChunkedInputStream implementation. @@ -189,12 +193,12 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag return messageList; } - private List<MailboxMessage> findMessagesInMailboxAfterUID(HBaseId mailboxId, long from, int batchSize, boolean flaggedForDelete) throws IOException { + private List<MailboxMessage> findMessagesInMailboxAfterUID(HBaseId mailboxId, MessageUid messageUid, int batchSize, boolean flaggedForDelete) throws IOException { List<MailboxMessage> messageList = new ArrayList<MailboxMessage>(); HTable messages = new HTable(conf, MESSAGES_TABLE); // uids are stored in reverse so we need to search - Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE), - messageRowKey(mailboxId, from - 1)); + + Scan scan = new Scan(messageRowKey(mailboxId, MessageUid.MAX_VALUE), previousMessageRowKey(mailboxId, messageUid)); if (flaggedForDelete) { SingleColumnValueFilter filter = new SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, MARKER_PRESENT); filter.setFilterIfMissing(true); @@ -219,16 +223,24 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag return messageList; } - private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(HBaseId mailboxId, long from, long to, int batchSize, boolean flaggedForDelete) throws IOException { + private byte[] previousMessageRowKey(HBaseId mailboxId, MessageUid messageUid) { + if (messageUid.isFirst()) { + return minMessageRowKey(mailboxId); + } else { + return messageRowKey(mailboxId, messageUid.previous()); + } + } + + private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(HBaseId mailboxId, MessageUid from, MessageUid to, int batchSize, boolean flaggedForDelete) throws IOException { List<MailboxMessage> messageList = new ArrayList<MailboxMessage>(); - if (from > to) { + if (from.compareTo(to) > 0) { return messageList; } HTable messages = new HTable(conf, MESSAGES_TABLE); /*TODO: check if Between should be inclusive or exclusive regarding limits. * HBase scan operaion are exclusive to the upper bound when providing stop row key. */ - Scan scan = new Scan(messageRowKey(mailboxId, to), messageRowKey(mailboxId, from - 1)); + Scan scan = new Scan(messageRowKey(mailboxId, to), previousMessageRowKey(mailboxId, from)); if (flaggedForDelete) { SingleColumnValueFilter filter = new SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, MARKER_PRESENT); filter.setFilterIfMissing(true); @@ -259,12 +271,12 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag } @Override - public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set) throws MailboxException { + public Map<MessageUid, MessageMetaData> expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set) throws MailboxException { try { - final Map<Long, MessageMetaData> data; + final Map<MessageUid, MessageMetaData> data; final List<MailboxMessage> results; - final long from = set.getUidFrom(); - final long to = set.getUidTo(); + final MessageUid from = set.getUidFrom(); + final MessageUid to = set.getUidTo(); HBaseId mailboxId = (HBaseId) mailbox.getMailboxId(); switch (set.getType()) { @@ -333,18 +345,15 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag try { messages = new HTable(conf, MESSAGES_TABLE); /* Limit the number of entries scanned to just the mails in this mailbox */ - Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE), - messageRowKey(mailboxId, 0)); + Scan scan = new Scan( + messageRowKey(mailboxId, MessageUid.MAX_VALUE), + minMessageRowKey(mailboxId)); scan.addFamily(MESSAGES_META_CF); scan.setFilter(new SingleColumnValueExcludeFilter(MESSAGES_META_CF, FLAGS_SEEN, CompareOp.EQUAL, MARKER_MISSING)); scan.setCaching(messages.getConfiguration().getInt("hbase.client.scanner.caching", 1) * 2); scan.setMaxVersions(1); scanner = messages.getScanner(scan); - long count = 0; - while (scanner.next() != null) { - count++; - } - return count; + return Iterables.size(scanner); } catch (IOException e) { throw new MailboxException("Search of first unseen message failed in mailbox " + mailbox, e); } finally { @@ -399,14 +408,16 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag } @Override - public Long findFirstUnseenMessageUid(Mailbox mailbox) throws MailboxException { + public MessageUid findFirstUnseenMessageUid(Mailbox mailbox) throws MailboxException { HTable messages = null; ResultScanner scanner = null; HBaseId mailboxId = (HBaseId) mailbox.getMailboxId(); try { messages = new HTable(conf, MESSAGES_TABLE); /* Limit the number of entries scanned to just the mails in this mailbox */ - Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE), messageRowKey(mailboxId, 0)); + Scan scan = new Scan( + messageRowKey(mailboxId, MessageUid.MAX_VALUE), + minMessageRowKey(mailboxId)); scan.addFamily(MESSAGES_META_CF); // filter out all rows with FLAGS_SEEN qualifier SingleColumnValueFilter filter = new SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_SEEN, CompareOp.EQUAL, MARKER_MISSING); @@ -415,13 +426,13 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag scan.setMaxVersions(1); scanner = messages.getScanner(scan); Result result; - Long lastUnseen = null; + MessageUid lastUnseen = null; byte[] row = null; while ((result = scanner.next()) != null) { row = result.getRow(); } if (row != null) { - lastUnseen = Long.MAX_VALUE - Bytes.toLong(row, 16, 8); + lastUnseen = MessageUid.of(Long.MAX_VALUE - Bytes.toLong(row, 16, 8)); } return lastUnseen; } catch (IOException e) { @@ -439,7 +450,7 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag } @Override - public List<Long> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException { + public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException { /** TODO: improve performance by implementing a last seen and last recent value per mailbox. * maybe one more call to HBase is less expensive than iterating throgh all rows. */ @@ -449,8 +460,9 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag try { messages = new HTable(conf, MESSAGES_TABLE); /* Limit the number of entries scanned to just the mails in this mailbox */ - Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE), - messageRowKey(mailboxId, 0)); + Scan scan = new Scan( + messageRowKey(mailboxId, MessageUid.MAX_VALUE), + minMessageRowKey(mailboxId)); // we add the column, if it exists, the message is recent, else it is not scan.addColumn(MESSAGES_META_CF, FLAGS_RECENT); SingleColumnValueFilter filter = new SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_RECENT, CompareOp.EQUAL, MARKER_PRESENT); @@ -460,9 +472,9 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag scanner = messages.getScanner(scan); Result result; - List<Long> uids = new ArrayList<Long>(); + List<MessageUid> uids = new ArrayList<MessageUid>(); while ((result = scanner.next()) != null) { - uids.add(Long.MAX_VALUE - Bytes.toLong(result.getRow(), 16, 8)); + uids.add(MessageUid.of(Long.MAX_VALUE - Bytes.toLong(result.getRow(), 16, 8))); } Collections.reverse(uids); return uids; @@ -551,13 +563,9 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag return updatedFlags.iterator(); } - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.MessageMapper#copy(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.store.mail.model.MailboxMessage) - */ @Override public MessageMetaData copy(Mailbox mailbox, MailboxMessage original) throws MailboxException { - long uid = uidProvider.nextUid(mailboxSession, mailbox); + MessageUid uid = uidProvider.nextUid(mailboxSession, mailbox); long modSeq = -1; if (modSeqProvider != null) { modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox); @@ -569,29 +577,17 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag return save(mailboxId, message); } - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.MessageMapper#copy(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.store.mail.model.MailboxMessage) - */ @Override public MessageMetaData move(Mailbox mailbox, MailboxMessage original) throws MailboxException { //TODO implement if possible throw new UnsupportedOperationException(); } - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.MessageMapper#getLastUid(org.apache.james.mailbox.store.mail.model.Mailbox) - */ @Override - public long getLastUid(Mailbox mailbox) throws MailboxException { + public Optional<MessageUid> getLastUid(Mailbox mailbox) throws MailboxException { return uidProvider.lastUid(mailboxSession, mailbox); } - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.MessageMapper#getHighestModSeq(org.apache.james.mailbox.store.mail.model.Mailbox) - */ @Override public long getHighestModSeq(Mailbox mailbox) throws MailboxException { return modSeqProvider.highestModSeq(mailboxSession, mailbox); @@ -674,11 +670,11 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag } } - private void deleteDeletedMessagesInMailboxWithUID(HBaseId mailboxId, long uid) throws IOException { + private void deleteDeletedMessagesInMailboxWithUID(HBaseId mailboxId, MessageUid from) throws IOException { //TODO: do I have to check if the message is flagged for delete here? HTable messages = new HTable(conf, MESSAGES_TABLE); HTable mailboxes = new HTable(conf, MAILBOXES_TABLE); - Delete delete = new Delete(messageRowKey(mailboxId, uid)); + Delete delete = new Delete(messageRowKey(mailboxId, from)); messages.delete(delete); mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, MAILBOX_MESSAGE_COUNT, -1); mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, MAILBOX_HIGHEST_MODSEQ, 1); @@ -686,7 +682,7 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag messages.close(); } - private void deleteDeletedMessagesInMailboxBetweenUIDs(HBaseId mailboxId, long fromUid, long toUid) throws IOException { + private void deleteDeletedMessagesInMailboxBetweenUIDs(HBaseId mailboxId, MessageUid fromUid, MessageUid toUid) throws IOException { HTable messages = new HTable(conf, MESSAGES_TABLE); HTable mailboxes = new HTable(conf, MAILBOXES_TABLE); List<Delete> deletes = new ArrayList<Delete>(); @@ -712,7 +708,7 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag messages.close(); } - private void deleteDeletedMessagesInMailboxAfterUID(HBaseId mailboxId, long fromUid) throws IOException { + private void deleteDeletedMessagesInMailboxAfterUID(HBaseId mailboxId, MessageUid fromUid) throws IOException { HTable messages = new HTable(conf, MESSAGES_TABLE); HTable mailboxes = new HTable(conf, MAILBOXES_TABLE); List<Delete> deletes = new ArrayList<Delete>(); @@ -745,7 +741,7 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag /*TODO: check if Between should be inclusive or exclusive regarding limits. * HBase scan operaion are exclusive to the upper bound when providing stop row key. */ - Scan scan = new Scan(customMessageRowKey(mailboxId, 0L), + Scan scan = new Scan(minMessageRowKey(mailboxId), new PrefixFilter(mailboxId.toBytes())); scan.addColumn(MESSAGES_META_CF, FLAGS_DELETED); SingleColumnValueFilter filter = new SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, MARKER_PRESENT); @@ -765,8 +761,8 @@ public class HBaseMessageMapper extends NonTransactionalMapper implements Messag messages.close(); } - private Map<Long, MessageMetaData> createMetaData(List<MailboxMessage> uids) { - final Map<Long, MessageMetaData> data = new HashMap<Long, MessageMetaData>(); + private Map<MessageUid, MessageMetaData> createMetaData(List<MailboxMessage> uids) { + final Map<MessageUid, MessageMetaData> data = new HashMap<MessageUid, MessageMetaData>(); for (MailboxMessage m : uids) { data.put(m.getUid(), new SimpleMessageMetaData(m)); } http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java index 23e667d..4079d57 100644 --- a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java +++ b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java @@ -30,10 +30,13 @@ import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.hbase.HBaseId; import org.apache.james.mailbox.store.mail.UidProvider; import org.apache.james.mailbox.store.mail.model.Mailbox; + +import com.google.common.base.Optional; /** * Message UidProvider for HBase. * @@ -52,10 +55,9 @@ public class HBaseUidProvider implements UidProvider { * @param session the session * @param mailbox the mailbox for which to get the last uid * @return the last uid used - * @throws MailboxException */ @Override - public long lastUid(MailboxSession session, Mailbox mailbox) throws MailboxException { + public Optional<MessageUid> lastUid(MailboxSession session, Mailbox mailbox) throws MailboxException { HTable mailboxes = null; HBaseId mailboxId = (HBaseId) mailbox.getMailboxId(); try { @@ -68,8 +70,11 @@ public class HBaseUidProvider implements UidProvider { if (result == null) { throw new MailboxException("Row or column not found!"); } - long uid = Bytes.toLong(result.getValue(MAILBOX_CF, MAILBOX_LASTUID)); - return uid; + long rawUid = Bytes.toLong(result.getValue(MAILBOX_CF, MAILBOX_LASTUID)); + if (rawUid == 0) { + return Optional.absent(); + } + return Optional.of(MessageUid.of(rawUid)); } catch (IOException e) { throw new MailboxException("lastUid", e); } finally { @@ -92,12 +97,12 @@ public class HBaseUidProvider implements UidProvider { * @throws MailboxException */ @Override - public long nextUid(MailboxSession session, Mailbox mailbox) throws MailboxException { + public MessageUid nextUid(MailboxSession session, Mailbox mailbox) throws MailboxException { HTable mailboxes = null; HBaseId mailboxId = (HBaseId) mailbox.getMailboxId(); try { mailboxes = new HTable(conf, MAILBOXES_TABLE); - long newValue = mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, MAILBOX_LASTUID, 1); + MessageUid newValue = MessageUid.of(mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, MAILBOX_LASTUID, 1)); mailboxes.close(); return newValue; } catch (IOException e) { http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java index d6fec12..d5ecb65 100644 --- a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java +++ b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java @@ -53,6 +53,7 @@ import javax.mail.Flags; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox; import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.store.mail.model.Property; @@ -147,6 +148,7 @@ public class HBaseUtilsTest { flags.add("userFlag2"); HBaseId uuid = HBaseId.of(UUID.randomUUID()); final SimpleMailboxMessage message = new SimpleMailboxMessage(new Date(), 100, 10, null, flags, new PropertyBuilder(), uuid); + message.setUid(MessageUid.of(1)); Put put = flagsToPut(message, flags); //test for the system flags assertTrue(put.has(MESSAGES_META_CF, FLAGS_SEEN, MARKER_PRESENT)); http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java index 56fb775..741c1fc 100644 --- a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java +++ b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java @@ -44,6 +44,7 @@ import javax.mail.util.SharedByteArrayInputStream; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.util.Bytes; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.hbase.HBaseClusterSingleton; import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox; import org.apache.james.mailbox.mock.MockMailboxSession; @@ -192,8 +193,8 @@ public class HBaseMailboxMessageMapperTest { */ private void testFindFirstUnseenMessageUid() throws Exception { LOG.info("findFirstUnseenMessageUid"); - final long uid = messageMapper.findFirstUnseenMessageUid(MBOXES.get(1)); - assertEquals(1, uid); + MessageUid uid = messageMapper.findFirstUnseenMessageUid(MBOXES.get(1)); + assertEquals(MessageUid.of(1), uid); } /** @@ -202,7 +203,7 @@ public class HBaseMailboxMessageMapperTest { */ private void testFindRecentMessageUidsInMailbox() throws Exception { LOG.info("findRecentMessageUidsInMailbox"); - List<Long> recentMessages = messageMapper.findRecentMessageUidsInMailbox(MBOXES.get(1)); + List<MessageUid> recentMessages = messageMapper.findRecentMessageUidsInMailbox(MBOXES.get(1)); assertEquals(MESSAGE_NO.size() - 1, recentMessages.size()); } @@ -222,8 +223,8 @@ public class HBaseMailboxMessageMapperTest { */ private void testGetLastUid() throws Exception { LOG.info("getLastUid"); - long lastUid = messageMapper.getLastUid(MBOXES.get(1)); - assertEquals(MESSAGE_NO.size(), lastUid); + MessageUid lastUid = messageMapper.getLastUid(MBOXES.get(1)).get(); + assertEquals(MessageUid.of(MESSAGE_NO.size()), lastUid); } /** http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java ---------------------------------------------------------------------- diff --git a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java index 627cde8..80c4695 100644 --- a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java +++ b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java @@ -22,6 +22,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.hbase.HBaseClusterSingleton; import static org.apache.james.mailbox.hbase.HBaseNames.*; import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox; @@ -32,6 +34,8 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Optional; + /** * Unit tests for UidProvider and ModSeqProvider. * @@ -113,12 +117,12 @@ public class HBaseUidAndModSeqProviderTest { mapper.save(newBox); mailboxList.add(newBox); pathsList.add(path); - - long result = uidProvider.lastUid(null, newBox); - assertEquals(0, result); + MailboxSession session = null; + Optional<MessageUid> result = uidProvider.lastUid(session, newBox); + assertEquals(Optional.absent(), result); for (int i = 1; i < 10; i++) { - long uid = uidProvider.nextUid(null, newBox); - assertEquals(uid, uidProvider.lastUid(null, newBox)); + MessageUid uid = uidProvider.nextUid(session, newBox); + assertEquals(uid, uidProvider.lastUid(session, newBox).get()); } } @@ -129,11 +133,16 @@ public class HBaseUidAndModSeqProviderTest { public void testNextUid() throws Exception { LOG.info("nextUid"); HBaseMailbox mailbox = mailboxList.get(mailboxList.size() / 2); - long lastUid = uidProvider.lastUid(null, mailbox); - long result; - for (int i = (int) lastUid + 1; i < (lastUid + 10); i++) { - result = uidProvider.nextUid(null, mailbox); - assertEquals(i, result); + MailboxSession session = null; + Optional<MessageUid> lastUid = uidProvider.lastUid(session, mailbox); + for (int i = 0; i < 10; i++) { + if (lastUid.isPresent()) { + lastUid = Optional.of(lastUid.get().next()); + } else { + lastUid = Optional.of(MessageUid.MIN_VALUE); + } + MessageUid result = uidProvider.nextUid(session, mailbox); + assertEquals(lastUid.get(), result); } } @@ -149,12 +158,12 @@ public class HBaseUidAndModSeqProviderTest { mapper.save(newBox); mailboxList.add(newBox); pathsList.add(path); - - long result = modSeqProvider.highestModSeq(null, newBox); + MailboxSession session = null; + long result = modSeqProvider.highestModSeq(session, newBox); assertEquals(0, result); for (int i = 1; i < 10; i++) { - long uid = modSeqProvider.nextModSeq(null, newBox); - assertEquals(uid, modSeqProvider.highestModSeq(null, newBox)); + long uid = modSeqProvider.nextModSeq(session, newBox); + assertEquals(uid, modSeqProvider.highestModSeq(session, newBox)); } } @@ -165,10 +174,11 @@ public class HBaseUidAndModSeqProviderTest { public void testNextModSeq() throws Exception { LOG.info("nextModSeq"); HBaseMailbox mailbox = mailboxList.get(mailboxList.size() / 2); - long lastUid = modSeqProvider.highestModSeq(null, mailbox); + MailboxSession session = null; + long lastUid = modSeqProvider.highestModSeq(session, mailbox); long result; for (int i = (int) lastUid + 1; i < (lastUid + 10); i++) { - result = modSeqProvider.nextModSeq(null, mailbox); + result = modSeqProvider.nextModSeq(session, mailbox); assertEquals(i, result); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java ---------------------------------------------------------------------- diff --git a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java index 51e9860..38d2387 100644 --- a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java +++ b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java @@ -39,6 +39,7 @@ import javax.jcr.query.QueryResult; import org.apache.jackrabbit.commons.JcrUtils; import org.apache.jackrabbit.util.ISO9075; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.jcr.JCRImapConstants; import org.apache.james.mailbox.jcr.MailboxSessionJCRRepository; @@ -297,8 +298,8 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo throws MailboxException { try { List<MailboxMessage> results; - long from = set.getUidFrom(); - final long to = set.getUidTo(); + MessageUid from = set.getUidFrom(); + final MessageUid to = set.getUidTo(); final Type type = set.getType(); switch (type) { @@ -332,11 +333,11 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo * @see org.apache.james.mailbox.store.mail.MessageMapper# * findRecentMessageUidsInMailbox () */ - public List<Long> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException { + public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException { try { - List<Long> list = new ArrayList<Long>(); + List<MessageUid> list = new ArrayList<MessageUid>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" + JCRMailboxMessage.RECENT_PROPERTY + "='true'] order by @" + JCRMailboxMessage.UID_PROPERTY; @@ -355,14 +356,8 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo } } - /* - * (non-Javadoc) - * - * @see - * org.apache.james.mailbox.store.mail.MessageMapper#findFirstUnseenMessageUid - * (org.apache.james.mailbox.store.mail.model.Mailbox) - */ - public Long findFirstUnseenMessageUid(Mailbox mailbox) throws MailboxException { + @Override + public MessageUid findFirstUnseenMessageUid(Mailbox mailbox) throws MailboxException { try { String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" + JCRMailboxMessage.SEEN_PROPERTY + "='false'] order by @" + JCRMailboxMessage.UID_PROPERTY; @@ -385,12 +380,12 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo } @Override - public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set) + public Map<MessageUid, MessageMetaData> expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set) throws MailboxException { try { final List<MailboxMessage> results; - final long from = set.getUidFrom(); - final long to = set.getUidTo(); + final MessageUid from = set.getUidFrom(); + final MessageUid to = set.getUidTo(); final Type type = set.getType(); switch (type) { default: @@ -407,9 +402,9 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo results = findDeletedMessagesInMailboxBetweenUIDs(mailbox, from, to); break; } - Map<Long, MessageMetaData> uids = new HashMap<Long, MessageMetaData>(); + Map<MessageUid, MessageMetaData> uids = new HashMap<MessageUid, MessageMetaData>(); for (MailboxMessage m : results) { - long uid = m.getUid(); + MessageUid uid = m.getUid(); uids.put(uid, new SimpleMessageMetaData(m)); delete(mailbox, m); } @@ -431,18 +426,18 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo } @Override - protected MessageMetaData copy(Mailbox mailbox, long uid, long modSeq, MailboxMessage original) + protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original) throws MailboxException { try { String newMessagePath = getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath() + NODE_DELIMITER - + String.valueOf(uid); + + String.valueOf(uid.asLong()); getSession().getWorkspace().copy( ((JCRMailboxMessage) original).getNode().getPath(), getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath() + NODE_DELIMITER - + String.valueOf(uid)); + + String.valueOf(uid.asLong())); Node node = getSession().getNode(newMessagePath); node.setProperty(JCRMailboxMessage.MAILBOX_UUID_PROPERTY, mailbox.getMailboxId().serialize()); - node.setProperty(JCRMailboxMessage.UID_PROPERTY, uid); + node.setProperty(JCRMailboxMessage.UID_PROPERTY, uid.asLong()); node.setProperty(JCRMailboxMessage.MODSEQ_PROPERTY, modSeq); // A copy of a message is recent // See MAILBOX-85 @@ -510,8 +505,8 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo } - long uid = membership.getUid(); - messageNode = mailboxNode.addNode(String.valueOf(uid), "nt:file"); + MessageUid uid = membership.getUid(); + messageNode = mailboxNode.addNode(String.valueOf(uid.asLong()), "nt:file"); messageNode.addMixin("jamesMailbox:message"); try { membership.merge(messageNode); @@ -545,11 +540,11 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo return ISO9075.encodePath(getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath()); } - private List<MailboxMessage> findMessagesInMailboxAfterUID(Mailbox mailbox, long uid, int batchSize) + private List<MailboxMessage> findMessagesInMailboxAfterUID(Mailbox mailbox, MessageUid from, int batchSize) throws RepositoryException { List<MailboxMessage> list = new ArrayList<MailboxMessage>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" - + JCRMailboxMessage.UID_PROPERTY + ">=" + uid + "] order by @" + JCRMailboxMessage.UID_PROPERTY; + + JCRMailboxMessage.UID_PROPERTY + ">=" + from + "] order by @" + JCRMailboxMessage.UID_PROPERTY; QueryManager manager = getSession().getWorkspace().getQueryManager(); Query query = manager.createQuery(queryString, XPATH_LANGUAGE); @@ -564,11 +559,11 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo return list; } - private List<MailboxMessage> findMessageInMailboxWithUID(Mailbox mailbox, long uid) + private List<MailboxMessage> findMessageInMailboxWithUID(Mailbox mailbox, MessageUid from) throws RepositoryException { List<MailboxMessage> list = new ArrayList<MailboxMessage>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" - + JCRMailboxMessage.UID_PROPERTY + "=" + uid + "]"; + + JCRMailboxMessage.UID_PROPERTY + "=" + from + "]"; QueryManager manager = getSession().getWorkspace().getQueryManager(); Query query = manager.createQuery(queryString, XPATH_LANGUAGE); @@ -581,7 +576,7 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo return list; } - private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(Mailbox mailbox, long from, long to, + private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(Mailbox mailbox, MessageUid from, MessageUid to, int batchSize) throws RepositoryException { List<MailboxMessage> list = new ArrayList<MailboxMessage>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" @@ -620,11 +615,11 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo return list; } - private List<MailboxMessage> findDeletedMessagesInMailboxAfterUID(Mailbox mailbox, long uid) + private List<MailboxMessage> findDeletedMessagesInMailboxAfterUID(Mailbox mailbox, MessageUid from) throws RepositoryException { List<MailboxMessage> list = new ArrayList<MailboxMessage>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" - + JCRMailboxMessage.UID_PROPERTY + ">=" + uid + " and @" + JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @" + + JCRMailboxMessage.UID_PROPERTY + ">=" + from + " and @" + JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @" + JCRMailboxMessage.UID_PROPERTY; QueryManager manager = getSession().getWorkspace().getQueryManager(); @@ -637,11 +632,11 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo return list; } - private List<MailboxMessage> findDeletedMessageInMailboxWithUID(Mailbox mailbox, long uid) + private List<MailboxMessage> findDeletedMessageInMailboxWithUID(Mailbox mailbox, MessageUid from) throws RepositoryException { List<MailboxMessage> list = new ArrayList<MailboxMessage>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" - + JCRMailboxMessage.UID_PROPERTY + "=" + uid + " and @" + JCRMailboxMessage.DELETED_PROPERTY + "='true']"; + + JCRMailboxMessage.UID_PROPERTY + "=" + from + " and @" + JCRMailboxMessage.DELETED_PROPERTY + "='true']"; QueryManager manager = getSession().getWorkspace().getQueryManager(); Query query = manager.createQuery(queryString, XPATH_LANGUAGE); query.setLimit(1); @@ -655,7 +650,7 @@ public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapCo return list; } - private List<MailboxMessage> findDeletedMessagesInMailboxBetweenUIDs(Mailbox mailbox, long from, long to) + private List<MailboxMessage> findDeletedMessagesInMailboxBetweenUIDs(Mailbox mailbox, MessageUid from, MessageUid to) throws RepositoryException { List<MailboxMessage> list = new ArrayList<MailboxMessage>(); String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@" http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java ---------------------------------------------------------------------- diff --git a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java index 21ba5f0..824f953 100644 --- a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java +++ b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java @@ -24,12 +24,15 @@ import javax.jcr.Session; import org.apache.james.mailbox.MailboxPathLocker; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.jcr.MailboxSessionJCRRepository; import org.apache.james.mailbox.jcr.mail.model.JCRMailbox; import org.apache.james.mailbox.store.mail.AbstractLockingUidProvider; import org.apache.james.mailbox.store.mail.model.Mailbox; +import com.google.common.base.Optional; + public class JCRUidProvider extends AbstractLockingUidProvider { private final MailboxSessionJCRRepository repository; @@ -40,11 +43,15 @@ public class JCRUidProvider extends AbstractLockingUidProvider { } @Override - public long lastUid(MailboxSession mailboxSession, Mailbox mailbox) throws MailboxException { + public Optional<MessageUid> lastUid(MailboxSession mailboxSession, Mailbox mailbox) throws MailboxException { try { Session s = repository.login(mailboxSession); Node node = s.getNodeByIdentifier(mailbox.getMailboxId().serialize()); - return node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong(); + long rawUid = node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong(); + if (rawUid == 0) { + return Optional.absent(); + } + return Optional.of(MessageUid.of(rawUid)); } catch (RepositoryException e) { throw new MailboxException("Unable to get last uid for mailbox " + mailbox, e); } @@ -52,15 +59,15 @@ public class JCRUidProvider extends AbstractLockingUidProvider { } @Override - protected long lockedNextUid(MailboxSession session, Mailbox mailbox) throws MailboxException { + protected MessageUid lockedNextUid(MailboxSession session, Mailbox mailbox) throws MailboxException { try { Session s = repository.login(session); Node node = s.getNodeByIdentifier(mailbox.getMailboxId().serialize()); - long uid = node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong(); - uid++; - node.setProperty(JCRMailbox.LASTUID_PROPERTY, uid); + MessageUid uid = MessageUid.of(node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong()); + MessageUid nextUid = uid.next(); + node.setProperty(JCRMailbox.LASTUID_PROPERTY, nextUid.asLong()); s.save(); - return uid; + return nextUid; } catch (RepositoryException e) { throw new MailboxException("Unable to consume next uid for mailbox " + mailbox, e); } http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java ---------------------------------------------------------------------- diff --git a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java index ec1bf07..32c0387 100644 --- a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java +++ b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; +import java.util.Comparator; import java.util.Date; import java.util.List; @@ -38,6 +39,7 @@ import org.apache.commons.io.input.BoundedInputStream; import org.apache.commons.lang.NotImplementedException; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.commons.JcrUtils; +import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.jcr.JCRId; import org.apache.james.mailbox.jcr.JCRImapConstants; @@ -48,13 +50,13 @@ import org.apache.james.mailbox.store.mail.model.FlagsBuilder; import org.apache.james.mailbox.store.mail.model.MailboxMessage; import org.apache.james.mailbox.store.mail.model.MessageId; import org.apache.james.mailbox.store.mail.model.Property; -import org.apache.james.mailbox.store.mail.model.impl.MessageUidComparator; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; +import org.apache.james.mailbox.store.search.comparator.UidComparator; import org.slf4j.Logger; public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, Persistent { - private static final MessageUidComparator MESSAGE_UID_COMPARATOR = new MessageUidComparator(); + private static final Comparator<MailboxMessage> MESSAGE_UID_COMPARATOR = new UidComparator(); private Node node; private final Logger logger; @@ -66,7 +68,7 @@ public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, Pers private int bodyStartOctet; private JCRId mailboxUUID; - private long uid; + private MessageUid uid; private Date internalDate; private long size; private boolean answered; @@ -131,7 +133,7 @@ public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, Pers /** * Create a copy of the given message */ - public JCRMailboxMessage(JCRId mailboxUUID, long uid, long modSeq, JCRMailboxMessage message, Logger logger) throws MailboxException { + public JCRMailboxMessage(JCRId mailboxUUID, MessageUid uid, long modSeq, JCRMailboxMessage message, Logger logger) throws MailboxException { this.mailboxUUID = mailboxUUID; this.internalDate = message.getInternalDate(); this.size = message.getFullContentOctets(); @@ -275,7 +277,7 @@ public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, Pers if (isPersistent() == false) { node.setProperty(SIZE_PROPERTY, getFullContentOctets()); node.setProperty(MAILBOX_UUID_PROPERTY, getMailboxId().serialize()); - node.setProperty(UID_PROPERTY, getUid()); + node.setProperty(UID_PROPERTY, getUid().asLong()); node.setProperty(MODSEQ_PROPERTY, getModSeq()); if (getInternalDate() == null) { @@ -409,15 +411,15 @@ public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, Pers @Override - public long getUid() { + public MessageUid getUid() { if (isPersistent()) { try { - return node.getProperty(UID_PROPERTY).getLong(); + return MessageUid.of(node.getProperty(UID_PROPERTY).getLong()); } catch (RepositoryException e) { logger.error("Unable to access property " + UID_PROPERTY, e); } - return 0; + return MessageUid.MIN_VALUE; } return uid; } @@ -653,10 +655,10 @@ public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, Pers } @Override - public void setUid(long uid) { + public void setUid(MessageUid uid) { if (isPersistent()) { try { - node.setProperty(UID_PROPERTY, uid); + node.setProperty(UID_PROPERTY, uid.asLong()); } catch (RepositoryException e) { logger.error("Unable to set uid", e); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
