Author: btellier Date: Wed Jun 17 09:10:17 2015 New Revision: 1685963 URL: http://svn.apache.org/r1685963 Log: MAILBOX-233 store message properties in Cassandra - Contributed by Antoine Duprat
Modified: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTypesProvider.java james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleProperty.java james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java Modified: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java (original) +++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java Wed Jun 17 09:10:17 2015 @@ -60,7 +60,7 @@ public class CassandraMailboxSessionMapp @Override public CassandraMessageMapper createMessageMapper(MailboxSession mailboxSession) { - return new CassandraMessageMapper(session, uidProvider, modSeqProvider); + return new CassandraMessageMapper(session, uidProvider, modSeqProvider, null, maxRetry, typesProvider); } @Override Modified: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java (original) +++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTableManager.java Wed Jun 17 09:10:17 2015 @@ -19,7 +19,14 @@ package org.apache.james.mailbox.cassandra; -import static com.datastax.driver.core.DataType.*; +import static com.datastax.driver.core.DataType.bigint; +import static com.datastax.driver.core.DataType.blob; +import static com.datastax.driver.core.DataType.cboolean; +import static com.datastax.driver.core.DataType.cint; +import static com.datastax.driver.core.DataType.counter; +import static com.datastax.driver.core.DataType.text; +import static com.datastax.driver.core.DataType.timestamp; +import static com.datastax.driver.core.DataType.timeuuid; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.schemabuilder.Create; @@ -73,8 +80,6 @@ public class CassandraTableManager { .addColumn(CassandraMessageTable.BODY_OCTECTS, cint()) .addColumn(CassandraMessageTable.TEXTUAL_LINE_COUNT, bigint()) .addColumn(CassandraMessageTable.MOD_SEQ, bigint()) - .addColumn(CassandraMessageTable.MEDIA_TYPE, text()) - .addColumn(CassandraMessageTable.SUB_TYPE, text()) .addColumn(CassandraMessageTable.FULL_CONTENT_OCTETS, cint()) .addColumn(CassandraMessageTable.BODY_CONTENT, blob()) .addColumn(CassandraMessageTable.HEADER_CONTENT, blob()) @@ -85,6 +90,7 @@ public class CassandraTableManager { .addColumn(CassandraMessageTable.Flag.RECENT, cboolean()) .addColumn(CassandraMessageTable.Flag.SEEN, cboolean()) .addColumn(CassandraMessageTable.Flag.USER, cboolean()) + .addUDTListColumn(CassandraMessageTable.PROPERTIES, SchemaBuilder.frozen(CassandraTypesProvider.TYPE.Property.getName())) .addColumn(CassandraMessageTable.FLAG_VERSION, bigint())), Subscription(CassandraSubscriptionTable.TABLE_NAME, SchemaBuilder.createTable(CassandraSubscriptionTable.TABLE_NAME) Modified: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTypesProvider.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTypesProvider.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTypesProvider.java (original) +++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraTypesProvider.java Wed Jun 17 09:10:17 2015 @@ -25,6 +25,7 @@ import com.datastax.driver.core.schemabu import com.datastax.driver.core.schemabuilder.SchemaBuilder; import com.google.common.collect.ImmutableMap; import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable; +import org.apache.james.mailbox.cassandra.table.CassandraMessageTable; import java.util.Arrays; import java.util.Optional; @@ -39,7 +40,13 @@ public class CassandraTypesProvider { SchemaBuilder.createType(CassandraMailboxTable.MAILBOX_BASE) .ifNotExists() .addColumn(CassandraMailboxTable.MailboxBase.NAMESPACE, text()) - .addColumn(CassandraMailboxTable.MailboxBase.USER, text())) + .addColumn(CassandraMailboxTable.MailboxBase.USER, text())), + Property(CassandraMessageTable.PROPERTIES, + SchemaBuilder.createType(CassandraMessageTable.PROPERTIES) + .ifNotExists() + .addColumn(CassandraMessageTable.Properties.NAMESPACE, text()) + .addColumn(CassandraMessageTable.Properties.NAME, text()) + .addColumn(CassandraMessageTable.Properties.VALUE, text())) ; private final String name; Modified: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java (original) +++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java Wed Jun 17 09:10:17 2015 @@ -30,6 +30,7 @@ import static com.datastax.driver.core.q import static com.datastax.driver.core.querybuilder.QueryBuilder.select; import static com.datastax.driver.core.querybuilder.QueryBuilder.set; import static com.datastax.driver.core.querybuilder.QueryBuilder.update; +import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Properties; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_CONTENT; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_OCTECTS; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_START_OCTET; @@ -40,9 +41,8 @@ import static org.apache.james.mailbox.c import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.IMAP_UID; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.INTERNAL_DATE; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MAILBOX_ID; -import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MEDIA_TYPE; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MOD_SEQ; -import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.SUB_TYPE; +import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.PROPERTIES; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.TABLE_NAME; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.TEXTUAL_LINE_COUNT; import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.ANSWERED; @@ -61,13 +61,18 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; import javax.mail.Flags; import javax.mail.Flags.Flag; import javax.mail.util.SharedByteArrayInputStream; +import com.datastax.driver.core.UDTValue; import org.apache.james.mailbox.FlagsBuilder; import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.cassandra.CassandraConstants; +import org.apache.james.mailbox.cassandra.CassandraTypesProvider; +import org.apache.james.mailbox.cassandra.CassandraTypesProvider.TYPE; import org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable; import org.apache.james.mailbox.cassandra.table.CassandraMessageTable; import org.apache.james.mailbox.exception.MailboxException; @@ -82,12 +87,14 @@ import org.apache.james.mailbox.store.ma import org.apache.james.mailbox.store.mail.model.Message; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; import org.apache.james.mailbox.store.mail.model.impl.SimpleMessage; +import org.apache.james.mailbox.store.mail.model.impl.SimpleProperty; import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; +import com.datastax.driver.core.TupleValue; import com.datastax.driver.core.querybuilder.Assignment; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; @@ -104,30 +111,31 @@ import com.google.common.primitives.Byte */ public class CassandraMessageMapper implements MessageMapper<UUID> { - private Session session; - private ModSeqProvider<UUID> modSeqProvider; - private MailboxSession mailboxSession; - private UidProvider<UUID> uidProvider; + private final Session session; + private final ModSeqProvider<UUID> modSeqProvider; + private final MailboxSession mailboxSession; + private final UidProvider<UUID> uidProvider; + private final CassandraTypesProvider typesProvider; - private final int applied = 0; private int maxRetries; private final static int DEFAULT_MAX_RETRIES = 10000; - public CassandraMessageMapper(Session session, UidProvider<UUID> uidProvider, ModSeqProvider<UUID> modSeqProvider) { - this(session, uidProvider, modSeqProvider, null, DEFAULT_MAX_RETRIES); + public CassandraMessageMapper(Session session, UidProvider<UUID> uidProvider, ModSeqProvider<UUID> modSeqProvider, CassandraTypesProvider typesProvider) { + this(session, uidProvider, modSeqProvider, null, DEFAULT_MAX_RETRIES, typesProvider); } - public CassandraMessageMapper(Session session, UidProvider<UUID> uidProvider, ModSeqProvider<UUID> modSeqProvider, MailboxSession mailboxSession) { - this(session, uidProvider, modSeqProvider, mailboxSession, DEFAULT_MAX_RETRIES); + public CassandraMessageMapper(Session session, UidProvider<UUID> uidProvider, ModSeqProvider<UUID> modSeqProvider, MailboxSession mailboxSession, CassandraTypesProvider typesProvider) { + this(session, uidProvider, modSeqProvider, mailboxSession, DEFAULT_MAX_RETRIES, typesProvider); } - public CassandraMessageMapper(Session session, UidProvider<UUID> uidProvider, ModSeqProvider<UUID> modSeqProvider, MailboxSession mailboxSession, int maxRetries) { + public CassandraMessageMapper(Session session, UidProvider<UUID> uidProvider, ModSeqProvider<UUID> modSeqProvider, MailboxSession mailboxSession, int maxRetries, CassandraTypesProvider typesProvider) { this.session = session; this.uidProvider = uidProvider; this.modSeqProvider = modSeqProvider; this.mailboxSession = mailboxSession; this.maxRetries = maxRetries; + this.typesProvider = typesProvider; } @Override @@ -206,9 +214,10 @@ public class CassandraMessageMapper impl } private PropertyBuilder getPropertyBuilder(Row row) { - PropertyBuilder property = new PropertyBuilder(); - property.setSubType(row.getString(SUB_TYPE)); - property.setMediaType(row.getString(MEDIA_TYPE)); + PropertyBuilder property = new PropertyBuilder( + row.getList(PROPERTIES, UDTValue.class).stream() + .map(x -> new SimpleProperty(x.getString(Properties.NAMESPACE), x.getString(Properties.NAME), x.getString(Properties.VALUE))) + .collect(Collectors.toList())); property.setTextualLineCount(row.getLong(TEXTUAL_LINE_COUNT)); return property; } @@ -326,9 +335,7 @@ public class CassandraMessageMapper impl .value(IMAP_UID, message.getUid()) .value(MOD_SEQ, message.getModSeq()) .value(INTERNAL_DATE, message.getInternalDate()) - .value(MEDIA_TYPE, message.getMediaType()) .value(BODY_START_OCTET, message.getFullContentOctets() - message.getBodyOctets()) - .value(SUB_TYPE, message.getSubType()) .value(FULL_CONTENT_OCTETS, message.getFullContentOctets()) .value(BODY_OCTECTS, message.getBodyOctets()) .value(ANSWERED, message.isAnswered()) @@ -340,6 +347,13 @@ public class CassandraMessageMapper impl .value(USER, message.createFlags().contains(Flag.USER)) .value(BODY_CONTENT, bindMarker()) .value(HEADER_CONTENT, bindMarker()) + .value(PROPERTIES, message.getProperties().stream() + .map(x -> typesProvider.getDefinedUserType(TYPE.Property) + .newValue() + .setString(Properties.NAMESPACE, x.getNamespace()) + .setString(Properties.NAME, x.getLocalName()) + .setString(Properties.VALUE, x.getValue())) + .collect(Collectors.toList())) .value(TEXTUAL_LINE_COUNT, message.getTextualLineCount()) .value(FLAG_VERSION, 0); PreparedStatement preparedStatement = session.prepare(query.toString()); @@ -368,7 +382,7 @@ public class CassandraMessageMapper impl .and(eq(MAILBOX_ID, message.getMailboxId())) .onlyIf(eq(FLAG_VERSION, flagVersion)) ); - return resultSet.one().getBool(applied); + return resultSet.one().getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED); } private ByteBuffer toByteBuffer(InputStream stream) throws IOException { Modified: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java (original) +++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java Wed Jun 17 09:10:17 2015 @@ -29,17 +29,15 @@ public interface CassandraMessageTable { String IMAP_UID = "uid"; String INTERNAL_DATE = "internalDate"; String BODY_START_OCTET = "bodyStartOctet"; - String CONTENT = "content"; String MOD_SEQ = "modSeq"; - String MEDIA_TYPE = "mediaType"; - String SUB_TYPE = "subType"; String FULL_CONTENT_OCTETS = "fullContentOctets"; String BODY_OCTECTS = "bodyOctets"; String TEXTUAL_LINE_COUNT = "textualLineCount"; String BODY_CONTENT = "bodyContent"; String HEADER_CONTENT = "headerContent"; + String PROPERTIES = "properties"; String FLAG_VERSION = "flagVersion"; - String[] FIELDS = { MAILBOX_ID, IMAP_UID, INTERNAL_DATE, MOD_SEQ, BODY_START_OCTET, MEDIA_TYPE, SUB_TYPE, FULL_CONTENT_OCTETS, BODY_OCTECTS, Flag.ANSWERED, Flag.DELETED, Flag.DRAFT, Flag.FLAGGED, Flag.RECENT, Flag.SEEN, Flag.USER, BODY_CONTENT, HEADER_CONTENT, TEXTUAL_LINE_COUNT, FLAG_VERSION }; + String[] FIELDS = { MAILBOX_ID, IMAP_UID, INTERNAL_DATE, MOD_SEQ, BODY_START_OCTET, FULL_CONTENT_OCTETS, BODY_OCTECTS, Flag.ANSWERED, Flag.DELETED, Flag.DRAFT, Flag.FLAGGED, Flag.RECENT, Flag.SEEN, Flag.USER, BODY_CONTENT, HEADER_CONTENT, TEXTUAL_LINE_COUNT, PROPERTIES, FLAG_VERSION }; interface Flag { String ANSWERED = "flagAnswered"; @@ -55,4 +53,10 @@ public interface CassandraMessageTable { .put(SEEN, javax.mail.Flags.Flag.SEEN).put(FLAGGED, javax.mail.Flags.Flag.FLAGGED).put(USER, javax.mail.Flags.Flag.USER).build(); } + + interface Properties { + String NAMESPACE = "namespace"; + String NAME = "name"; + String VALUE = "value"; + } } Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleProperty.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleProperty.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleProperty.java (original) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleProperty.java Wed Jun 17 09:10:17 2015 @@ -99,4 +99,23 @@ public final class SimpleProperty implem + "' value='" + this.value + "')"; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SimpleProperty)) return false; + SimpleProperty that = (SimpleProperty) o; + if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) return false; + if (localName != null ? !localName.equals(that.localName) : that.localName != null) return false; + return !(value != null ? !value.equals(that.value) : that.value != null); + + } + + @Override + public int hashCode() { + int result = namespace != null ? namespace.hashCode() : 0; + result = 31 * result + (localName != null ? localName.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } } Modified: james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java?rev=1685963&r1=1685962&r2=1685963&view=diff ============================================================================== --- james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java (original) +++ james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java Wed Jun 17 09:10:17 2015 @@ -26,6 +26,7 @@ import org.apache.james.mailbox.model.Me import org.apache.james.mailbox.model.MessageRange; import org.apache.james.mailbox.model.UpdatedFlags; import org.apache.james.mailbox.store.mail.MessageMapper; +import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox; import org.apache.james.mailbox.store.mail.model.impl.SimpleMessage; @@ -73,12 +74,12 @@ public abstract class AbstractMessageMap messageMapper = mapperProvider.createMessageMapper(); benwaInboxMailbox = createMailbox(new MailboxPath("#private", "benwa", "INBOX")); benwaWorkMailbox = createMailbox( new MailboxPath("#private", "benwa", "INBOX"+DELIMITER+"work")); - message1 = createMessage(benwaInboxMailbox, "Subject: Test1 \n\nBody1\n.\n", BODY_START); - message2 = createMessage(benwaInboxMailbox, "Subject: Test2 \n\nBody2\n.\n", BODY_START); - message3 = createMessage(benwaInboxMailbox, "Subject: Test3 \n\nBody3\n.\n", BODY_START); - message4 = createMessage(benwaInboxMailbox, "Subject: Test4 \n\nBody4\n.\n", BODY_START); - message5 = createMessage(benwaInboxMailbox, "Subject: Test5 \n\nBody5\n.\n", BODY_START); - message6 = createMessage(benwaWorkMailbox, "Subject: Test6 \n\nBody6\n.\n", BODY_START); + message1 = createMessage(benwaInboxMailbox, "Subject: Test1 \n\nBody1\n.\n", BODY_START, new PropertyBuilder()); + message2 = createMessage(benwaInboxMailbox, "Subject: Test2 \n\nBody2\n.\n", BODY_START, new PropertyBuilder()); + message3 = createMessage(benwaInboxMailbox, "Subject: Test3 \n\nBody3\n.\n", BODY_START, new PropertyBuilder()); + message4 = createMessage(benwaInboxMailbox, "Subject: Test4 \n\nBody4\n.\n", BODY_START, new PropertyBuilder()); + message5 = createMessage(benwaInboxMailbox, "Subject: Test5 \n\nBody5\n.\n", BODY_START, new PropertyBuilder()); + message6 = createMessage(benwaWorkMailbox, "Subject: Test6 \n\nBody6\n.\n", BODY_START, new PropertyBuilder()); } @After @@ -534,7 +535,78 @@ public abstract class AbstractMessageMap assertThat(messageMapper.updateFlags(benwaInboxMailbox, new Flags(Flags.Flag.SEEN), false, true, MessageRange.all())) .hasSize(5); } - + + @Test + public void messagePropertiesShouldBeStored() throws Exception { + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setMediaType("text"); + propBuilder.setSubType("html"); + propBuilder.setTextualLineCount(2L); + propBuilder.setProperty(StandardNames.NAMESPACE_RFC_2045, StandardNames.MIME_CONTENT_TRANSFER_ENCODING_NAME, "7bit"); + propBuilder.setProperty(StandardNames.MIME_CONTENT_TYPE_PARAMETER_SPACE, StandardNames.MIME_CONTENT_TYPE_PARAMETER_CHARSET_NAME, "US-ASCII"); + + SimpleMessage<Id> messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStored \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + Message<Id> message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getProperties()).containsOnlyElementsOf(propBuilder.toProperties()); + } + + @Test + public void messagePropertiesShouldBeStoredWhenDuplicateEntries() throws Exception { + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setProperty(StandardNames.MIME_CONTENT_LANGUAGE_SPACE, StandardNames.MIME_CONTENT_LANGUAGE_NAME, "us"); + propBuilder.setProperty(StandardNames.MIME_CONTENT_LANGUAGE_SPACE, StandardNames.MIME_CONTENT_LANGUAGE_NAME, "fr"); + + SimpleMessage<Id> messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + Message<Id> message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getProperties()).containsOnlyElementsOf(propBuilder.toProperties()); + } + + @Test + public void messagePropertiesShouldBeStoredWhenNoProperty() throws Exception { + SimpleMessage<Id> messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenNoProperty \n\nBody\n.\n", BODY_START, new PropertyBuilder()); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + Message<Id> message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getProperties()).isEmpty(); + } + + @Test + public void textualLineCountShouldBeWellStored() throws Exception { + long textualLineCount = 48L; + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setTextualLineCount(textualLineCount); + + SimpleMessage<Id> messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + Message<Id> message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getTextualLineCount()).isEqualTo(textualLineCount); + } + + @Test + public void mediaTypeShouldBeWellStored() throws Exception { + String mediaType = "plain"; + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setMediaType(mediaType); + + SimpleMessage<Id> messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + Message<Id> message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getMediaType()).isEqualTo(mediaType); + } + + @Test + public void subTypeShouldBeWellStored() throws Exception { + String subType = "text"; + PropertyBuilder propBuilder = new PropertyBuilder(); + propBuilder.setSubType(subType); + + SimpleMessage<Id> messageWithProperties = createMessage(benwaWorkMailbox, "Subject: messagePropertiesShouldBeStoredWhenDuplicateEntries \n\nBody\n.\n", BODY_START, propBuilder); + MessageMetaData messageMetaData = messageMapper.add(benwaInboxMailbox, messageWithProperties); + Message<Id> message = messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(messageMetaData.getUid()), FetchType.Body, 1).next(); + assertThat(message.getSubType()).isEqualTo(subType); + } + private Map<Long, MessageMetaData> markThenPerformExpunge(MessageRange range) throws MailboxException { messageMapper.updateFlags(benwaInboxMailbox, new Flags(Flags.Flag.DELETED), true, true, MessageRange.one(message1.getUid())); messageMapper.updateFlags(benwaInboxMailbox, new Flags(Flags.Flag.DELETED), true, true, MessageRange.one(message4.getUid())); @@ -567,7 +639,7 @@ public abstract class AbstractMessageMap return messageMapper.findInMailbox(benwaInboxMailbox, MessageRange.one(message.getUid()), MessageMapper.FetchType.Metadata, LIMIT).next(); } - private SimpleMessage<Id> createMessage(Mailbox<Id> mailbox, String content, int bodyStart) { - return new SimpleMessage<Id>(new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), new PropertyBuilder(), mailbox.getMailboxId()); + private SimpleMessage<Id> createMessage(Mailbox<Id> mailbox, String content, int bodyStart, PropertyBuilder propertyBuilder) { + return new SimpleMessage<Id>(new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, mailbox.getMailboxId()); } } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org