This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit f407fba4e6a638610dc4fd99844df45146421cb2 Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Mon Jan 20 11:44:58 2020 +0700 [REFACTORING] Favor composition over inheritance in order to parse and store attachments This enables the parse-then-store behaviour factorisation --- .../org/apache/james/mailbox/AttachmentStorer.java | 44 +++++++++++++++ .../mailbox/cassandra/CassandraMessageManager.java | 24 +------- .../mailbox/jpa/openjpa/OpenJPAMailboxManager.java | 1 - .../mailbox/jpa/openjpa/OpenJPAMessageManager.java | 8 +-- .../mailbox/inmemory/InMemoryMessageManager.java | 21 +------ .../james/mailbox/store/StoreAttachmentStorer.java | 65 ++++++++++++++++++++++ .../james/mailbox/store/StoreMailboxManager.java | 6 +- .../james/mailbox/store/StoreMessageManager.java | 30 ++-------- 8 files changed, 129 insertions(+), 70 deletions(-) diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java new file mode 100644 index 0000000..2a3e22b --- /dev/null +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java @@ -0,0 +1,44 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox; + +import java.util.List; + +import javax.mail.internet.SharedInputStream; + +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.MessageAttachment; +import org.apache.james.mailbox.model.MessageId; + +import com.google.common.collect.ImmutableList; + +public interface AttachmentStorer { + /** + * If applicable, this method will parse the messageContent to retrieve associated attachments and will store them. + */ + List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException; + + class NoopAttachmentStorer implements AttachmentStorer { + @Override + public List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) { + return ImmutableList.of(); + } + } +} diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java index 50159cd..c22aba9 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java @@ -19,24 +19,19 @@ package org.apache.james.mailbox.cassandra; -import java.util.List; - import javax.mail.Flags; -import javax.mail.internet.SharedInputStream; import org.apache.james.mailbox.MailboxPathLocker; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.events.EventBus; -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.Mailbox; -import org.apache.james.mailbox.model.MessageAttachment; import org.apache.james.mailbox.model.MessageId; -import org.apache.james.mailbox.model.ParsedAttachment; import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; import org.apache.james.mailbox.store.BatchSizes; import org.apache.james.mailbox.store.MessageFactory; import org.apache.james.mailbox.store.PreDeletionHooks; +import org.apache.james.mailbox.store.StoreAttachmentStorer; import org.apache.james.mailbox.store.StoreMessageManager; import org.apache.james.mailbox.store.StoreRightManager; import org.apache.james.mailbox.store.mail.model.impl.MessageParser; @@ -44,12 +39,9 @@ import org.apache.james.mailbox.store.search.MessageSearchIndex; /** * Cassandra implementation of {@link StoreMessageManager} - * */ public class CassandraMessageManager extends StoreMessageManager { - private CassandraMailboxSessionMapperFactory mapperFactory; - CassandraMessageManager(CassandraMailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, EventBus eventBus, MailboxPathLocker locker, Mailbox mailbox, QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory, @@ -57,10 +49,8 @@ public class CassandraMessageManager extends StoreMessageManager { StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks) { super(CassandraMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox, - quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager, - preDeletionHooks, new MessageFactory.StoreMessageFactory()); - - this.mapperFactory = mapperFactory; + quotaManager, quotaRootResolver, messageIdFactory, batchSizes, storeRightManager, + preDeletionHooks, new MessageFactory.StoreMessageFactory(), new StoreAttachmentStorer(mapperFactory, messageParser)); } /** @@ -72,12 +62,4 @@ public class CassandraMessageManager extends StoreMessageManager { flags.add(Flags.Flag.USER); return flags; } - - @Override - protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException { - List<ParsedAttachment> attachments = extractAttachments(content); - return mapperFactory.getAttachmentMapper(session) - .storeAttachmentsForMessage(attachments, messageId); - } - } diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java index 3fec6d5..764868d 100644 --- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java +++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java @@ -75,7 +75,6 @@ public class OpenJPAMailboxManager extends StoreMailboxManager { mailboxRow, getQuotaComponents().getQuotaManager(), getQuotaComponents().getQuotaRootResolver(), - getMessageParser(), getMessageIdFactory(), configuration.getBatchSizes(), getStoreRightManager()); diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java index 6db978a..d982497 100644 --- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java +++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java @@ -21,6 +21,7 @@ package org.apache.james.mailbox.jpa.openjpa; import javax.mail.Flags; +import org.apache.james.mailbox.AttachmentStorer; import org.apache.james.mailbox.MailboxPathLocker; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.events.EventBus; @@ -34,7 +35,6 @@ import org.apache.james.mailbox.store.PreDeletionHooks; import org.apache.james.mailbox.store.StoreMailboxManager; import org.apache.james.mailbox.store.StoreMessageManager; import org.apache.james.mailbox.store.StoreRightManager; -import org.apache.james.mailbox.store.mail.model.impl.MessageParser; import org.apache.james.mailbox.store.search.MessageSearchIndex; /** @@ -45,12 +45,12 @@ public class OpenJPAMessageManager extends StoreMessageManager { public OpenJPAMessageManager(MailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, EventBus eventBus, MailboxPathLocker locker, Mailbox mailbox, - QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, + QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageId.Factory messageIdFactory, BatchSizes batchSizes, StoreRightManager storeRightManager) { super(StoreMailboxManager.DEFAULT_NO_MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox, - quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK, - new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None)); + quotaManager, quotaRootResolver, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK, + new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None), new AttachmentStorer.NoopAttachmentStorer()); } /** diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java index d8d1a96..5d51bb7 100644 --- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java +++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java @@ -1,33 +1,25 @@ package org.apache.james.mailbox.inmemory; -import java.util.List; - import javax.mail.Flags; -import javax.mail.internet.SharedInputStream; import org.apache.james.mailbox.MailboxPathLocker; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.events.EventBus; -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.Mailbox; -import org.apache.james.mailbox.model.MessageAttachment; import org.apache.james.mailbox.model.MessageId; -import org.apache.james.mailbox.model.ParsedAttachment; import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; import org.apache.james.mailbox.store.BatchSizes; import org.apache.james.mailbox.store.MailboxSessionMapperFactory; import org.apache.james.mailbox.store.MessageFactory; import org.apache.james.mailbox.store.PreDeletionHooks; +import org.apache.james.mailbox.store.StoreAttachmentStorer; import org.apache.james.mailbox.store.StoreMessageManager; import org.apache.james.mailbox.store.StoreRightManager; import org.apache.james.mailbox.store.mail.model.impl.MessageParser; import org.apache.james.mailbox.store.search.MessageSearchIndex; public class InMemoryMessageManager extends StoreMessageManager { - - private InMemoryMailboxSessionMapperFactory mapperFactory; - public InMemoryMessageManager(MailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, EventBus eventBus, @@ -42,8 +34,8 @@ public class InMemoryMessageManager extends StoreMessageManager { PreDeletionHooks preDeletionHooks) { super(InMemoryMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox, quotaManager, quotaRootResolver, - messageParser, messageIdFactory, batchSizes, storeRightManager, preDeletionHooks, new MessageFactory.StoreMessageFactory()); - this.mapperFactory = (InMemoryMailboxSessionMapperFactory) mapperFactory; + messageIdFactory, batchSizes, storeRightManager, preDeletionHooks, new MessageFactory.StoreMessageFactory(), + new StoreAttachmentStorer((InMemoryMailboxSessionMapperFactory) mapperFactory, messageParser)); } @Override @@ -52,11 +44,4 @@ public class InMemoryMessageManager extends StoreMessageManager { permanentFlags.add(Flags.Flag.USER); return permanentFlags; } - - @Override - protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException { - List<ParsedAttachment> attachments = extractAttachments(content); - return mapperFactory.getAttachmentMapper(session) - .storeAttachmentsForMessage(attachments, messageId); - } } diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java new file mode 100644 index 0000000..5ff314b --- /dev/null +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java @@ -0,0 +1,65 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store; + +import java.util.List; + +import javax.mail.internet.SharedInputStream; + +import org.apache.james.mailbox.AttachmentStorer; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.MessageAttachment; +import org.apache.james.mailbox.model.MessageId; +import org.apache.james.mailbox.model.ParsedAttachment; +import org.apache.james.mailbox.store.mail.AttachmentMapperFactory; +import org.apache.james.mailbox.store.mail.model.impl.MessageParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; + +public class StoreAttachmentStorer implements AttachmentStorer { + private static final Logger LOGGER = LoggerFactory.getLogger(StoreAttachmentStorer.class); + + private final AttachmentMapperFactory mapperFactory; + private final MessageParser messageParser; + + public StoreAttachmentStorer(AttachmentMapperFactory mapperFactory, MessageParser messageParser) { + this.mapperFactory = mapperFactory; + this.messageParser = messageParser; + } + + @Override + public List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException { + List<ParsedAttachment> attachments = extractAttachments(messageContent); + return mapperFactory.getAttachmentMapper(session) + .storeAttachmentsForMessage(attachments, messageId); + } + + private List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) { + try { + return messageParser.retrieveAttachments(contentIn.newStream(0, -1)); + } catch (Exception e) { + LOGGER.warn("Error while parsing mail's attachments: {}", e.getMessage(), e); + return ImmutableList.of(); + } + } +} diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java index aad8189..96cc2a5 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java @@ -33,6 +33,7 @@ import javax.inject.Inject; import org.apache.james.core.Username; import org.apache.james.core.quota.QuotaCountUsage; import org.apache.james.core.quota.QuotaSizeUsage; +import org.apache.james.mailbox.AttachmentStorer.NoopAttachmentStorer; import org.apache.james.mailbox.MailboxAnnotationManager; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxPathLocker; @@ -248,8 +249,9 @@ public class StoreMailboxManager implements MailboxManager { protected StoreMessageManager createMessageManager(Mailbox mailbox, MailboxSession session) throws MailboxException { return new StoreMessageManager(DEFAULT_NO_MESSAGE_CAPABILITIES, getMapperFactory(), getMessageSearchIndex(), getEventBus(), getLocker(), mailbox, quotaManager, - getQuotaComponents().getQuotaRootResolver(), getMessageParser(), getMessageIdFactory(), configuration.getBatchSizes(), - getStoreRightManager(), preDeletionHooks, new MessageFactory.StoreMessageFactory()); + getQuotaComponents().getQuotaRootResolver(), getMessageIdFactory(), configuration.getBatchSizes(), + getStoreRightManager(), preDeletionHooks, new MessageFactory.StoreMessageFactory(), + new NoopAttachmentStorer()); } @Override diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java index f37279a..0006c6f 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java @@ -45,6 +45,7 @@ import javax.mail.util.SharedFileInputStream; import org.apache.commons.io.input.TeeInputStream; import org.apache.commons.lang3.tuple.Pair; +import org.apache.james.mailbox.AttachmentStorer; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxManager.MessageCapabilities; import org.apache.james.mailbox.MailboxPathLocker; @@ -73,7 +74,6 @@ import org.apache.james.mailbox.model.MessageMetaData; import org.apache.james.mailbox.model.MessageMoves; import org.apache.james.mailbox.model.MessageRange; import org.apache.james.mailbox.model.MessageResultIterator; -import org.apache.james.mailbox.model.ParsedAttachment; import org.apache.james.mailbox.model.SearchQuery; import org.apache.james.mailbox.model.UidValidity; import org.apache.james.mailbox.model.UpdatedFlags; @@ -83,7 +83,6 @@ import org.apache.james.mailbox.store.event.EventFactory; 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.MailboxMessage; -import org.apache.james.mailbox.store.mail.model.impl.MessageParser; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; import org.apache.james.mailbox.store.quota.QuotaChecker; import org.apache.james.mailbox.store.search.MessageSearchIndex; @@ -100,8 +99,6 @@ import org.apache.james.util.IteratorWrapper; import org.apache.james.util.io.BodyOffsetInputStream; import org.apache.james.util.io.InputStreamConsummer; import org.apache.james.util.streams.Iterators; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.github.steveash.guavate.Guavate; import com.google.common.collect.ImmutableList; @@ -148,8 +145,6 @@ public class StoreMessageManager implements MessageManager { MINIMAL_PERMANET_FLAGS.add(Flags.Flag.SEEN); } - private static final Logger LOG = LoggerFactory.getLogger(StoreMessageManager.class); - private final EnumSet<MailboxManager.MessageCapabilities> messageCapabilities; private final EventBus eventBus; private final Mailbox mailbox; @@ -159,17 +154,17 @@ public class StoreMessageManager implements MessageManager { private final QuotaManager quotaManager; private final QuotaRootResolver quotaRootResolver; private final MailboxPathLocker locker; - private final MessageParser messageParser; private final Factory messageIdFactory; private final BatchSizes batchSizes; private final PreDeletionHooks preDeletionHooks; private final MessageFactory messageFactory; + private final AttachmentStorer attachmentStorer; public StoreMessageManager(EnumSet<MessageCapabilities> messageCapabilities, MailboxSessionMapperFactory mapperFactory, MessageSearchIndex index, EventBus eventBus, MailboxPathLocker locker, Mailbox mailbox, - QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, Factory messageIdFactory, BatchSizes batchSizes, - StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageFactory messageFactory) { + QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, Factory messageIdFactory, BatchSizes batchSizes, + StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageFactory messageFactory, AttachmentStorer attachmentStorer) { this.messageCapabilities = messageCapabilities; this.eventBus = eventBus; this.mailbox = mailbox; @@ -178,12 +173,12 @@ public class StoreMessageManager implements MessageManager { this.locker = locker; this.quotaManager = quotaManager; this.quotaRootResolver = quotaRootResolver; - this.messageParser = messageParser; this.messageIdFactory = messageIdFactory; this.batchSizes = batchSizes; this.storeRightManager = storeRightManager; this.preDeletionHooks = preDeletionHooks; this.messageFactory = messageFactory; + this.attachmentStorer = attachmentStorer; } /** @@ -492,15 +487,6 @@ public class StoreMessageManager implements MessageManager { return propertyBuilder; } - protected List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) { - try { - return messageParser.retrieveAttachments(contentIn.newStream(0, -1)); - } catch (Exception e) { - LOG.warn("Error while parsing mail's attachments: {}", e.getMessage(), e); - return ImmutableList.of(); - } - } - @Override public boolean isWriteable(MailboxSession session) throws MailboxException { return storeRightManager.isReadWrite(session, mailbox, getSharedPermanentFlags(session)); @@ -662,17 +648,13 @@ public class StoreMessageManager implements MessageManager { MessageId messageId = messageIdFactory.generate(); return mapperFactory.getMessageMapper(session).execute(() -> { - List<MessageAttachment> attachments = storeAttachments(messageId, content, session); + List<MessageAttachment> attachments = attachmentStorer.storeAttachments(messageId, content, session); MailboxMessage message = messageFactory.createMessage(messageId, getMailboxEntity(), internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments); MessageMetaData metadata = messageMapper.add(getMailboxEntity(), message); return Pair.of(metadata, attachments); }); } - protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException { - return ImmutableList.of(); - } - @Override public long getMessageCount(MailboxSession mailboxSession) throws MailboxException { return mapperFactory.getMessageMapper(mailboxSession).countMessagesInMailbox(getMailboxEntity()); --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org