You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2017/01/09 09:13:31 UTC
[3/6] james-project git commit: MAILBOX-279: JPAMessageMapper will
extends JPATransactionalMapper as the standard for all JPA
MAILBOX-279: JPAMessageMapper will extends JPATransactionalMapper as the standard for all JPA
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a377d438
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a377d438
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a377d438
Branch: refs/heads/master
Commit: a377d4386db26b57ae34f9a08d7599a0e85e5584
Parents: d4debb5
Author: Quynh Nguyen <qn...@linagora.com>
Authored: Wed Dec 7 14:11:50 2016 +0700
Committer: Quynh Nguyen <qn...@linagora.com>
Committed: Mon Jan 9 15:11:51 2017 +0700
----------------------------------------------------------------------
.../mailbox/jpa/mail/JPAMessageMapper.java | 175 ++++++++++---------
.../mailbox/store/mail/MessageMetadata.java | 69 ++++++++
2 files changed, 165 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/a377d438/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
index 84c4c22..b7542c6 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
@@ -23,9 +23,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.persistence.EntityManager;
+import javax.mail.Flags;
import javax.persistence.EntityManagerFactory;
-import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
@@ -33,6 +32,7 @@ import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.jpa.JPAId;
+import org.apache.james.mailbox.jpa.JPATransactionalMapper;
import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
import org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMailboxMessage;
import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMailboxMessage;
@@ -41,85 +41,29 @@ import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMailboxMessag
import org.apache.james.mailbox.model.MessageMetaData;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MessageRange.Type;
+import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
import org.apache.james.mailbox.store.SimpleMessageMetaData;
-import org.apache.james.mailbox.store.mail.AbstractMessageMapper;
import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.MessageMetadata;
import org.apache.james.mailbox.store.mail.ModSeqProvider;
import org.apache.james.mailbox.store.mail.UidProvider;
import org.apache.james.mailbox.store.mail.model.Mailbox;
import org.apache.james.mailbox.store.mail.model.MailboxMessage;
import org.apache.openjpa.persistence.ArgumentException;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
/**
* JPA implementation of a {@link MessageMapper}. This class is not thread-safe!
*/
-public class JPAMessageMapper extends AbstractMessageMapper implements MessageMapper {
- protected EntityManagerFactory entityManagerFactory;
- protected EntityManager entityManager;
-
- public JPAMessageMapper(MailboxSession session, UidProvider uidProvider,
- ModSeqProvider modSeqProvider, EntityManagerFactory entityManagerFactory) {
- super(session, uidProvider, modSeqProvider);
- this.entityManagerFactory = entityManagerFactory;
- }
-
- /**
- * Return the currently used {@link EntityManager} or a new one if none
- * exists.
- *
- * @return entitymanger
- */
- public EntityManager getEntityManager() {
- if (entityManager != null)
- return entityManager;
- entityManager = entityManagerFactory.createEntityManager();
- return entityManager;
- }
+public class JPAMessageMapper extends JPATransactionalMapper implements MessageMapper {
+ private final MessageMetadata messageMetadataMapper;
- /**
- * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#begin()
- */
- protected void begin() throws MailboxException {
- try {
- getEntityManager().getTransaction().begin();
- } catch (PersistenceException e) {
- throw new MailboxException("Begin of transaction failed", e);
- }
- }
-
- /**
- * Commit the Transaction and close the EntityManager
- */
- protected void commit() throws MailboxException {
- try {
- getEntityManager().getTransaction().commit();
- } catch (PersistenceException e) {
- throw new MailboxException("Commit of transaction failed", e);
- }
- }
-
- /**
- * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#rollback()
- */
- protected void rollback() throws MailboxException {
- EntityTransaction transaction = entityManager.getTransaction();
- // check if we have a transaction to rollback
- if (transaction.isActive()) {
- getEntityManager().getTransaction().rollback();
- }
- }
-
- /**
- * Close open {@link EntityManager}
- */
- public void endRequest() {
- if (entityManager != null) {
- if (entityManager.isOpen())
- entityManager.close();
- entityManager = null;
- }
+ public JPAMessageMapper(MailboxSession mailboxSession, UidProvider uidProvider, ModSeqProvider modSeqProvider, EntityManagerFactory entityManagerFactory) {
+ super(entityManagerFactory);
+ this.messageMetadataMapper = new MessageMetadata(mailboxSession, uidProvider, modSeqProvider);
}
/**
@@ -127,6 +71,7 @@ public class JPAMessageMapper extends AbstractMessageMapper implements MessageMa
* org.apache.james.mailbox.model.MessageRange,
* org.apache.james.mailbox.store.mail.MessageMapper.FetchType, int)
*/
+ @Override
public Iterator<MailboxMessage> findInMailbox(Mailbox mailbox, MessageRange set, FetchType fType, int max)
throws MailboxException {
try {
@@ -191,12 +136,22 @@ public class JPAMessageMapper extends AbstractMessageMapper implements MessageMa
*/
public void delete(Mailbox mailbox, MailboxMessage message) throws MailboxException {
try {
- getEntityManager().remove(message);
+ AbstractJPAMailboxMessage jpaMessage = getEntityManager().find(AbstractJPAMailboxMessage.class, buildKey(mailbox, message));
+ getEntityManager().remove(jpaMessage);
+
} catch (PersistenceException e) {
throw new MailboxException("Delete of message " + message + " failed in mailbox " + mailbox, e);
}
}
+ private AbstractJPAMailboxMessage.MailboxIdUidKey buildKey(Mailbox mailbox, MailboxMessage message) {
+ JPAId mailboxId = (JPAId) mailbox.getMailboxId();
+ AbstractJPAMailboxMessage.MailboxIdUidKey key = new AbstractJPAMailboxMessage.MailboxIdUidKey();
+ key.mailbox = mailboxId.getRawId();
+ key.uid = message.getUid().asLong();
+ return key;
+ }
+
@Override
@SuppressWarnings("unchecked")
public MessageUid findFirstUnseenMessageUid(Mailbox mailbox) throws MailboxException {
@@ -262,8 +217,8 @@ public class JPAMessageMapper extends AbstractMessageMapper implements MessageMa
default:
case ALL:
results = findDeletedMessagesInMailbox(mailboxId);
- data = createMetaData(results);
deleteDeletedMessagesInMailbox(mailboxId);
+ data = createMetaData(results);
break;
}
@@ -285,15 +240,71 @@ public class JPAMessageMapper extends AbstractMessageMapper implements MessageMa
}
@Override
- protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
+ public MessageMetaData add(Mailbox mailbox, MailboxMessage message) throws MailboxException {
+ messageMetadataMapper.enrichMessage(mailbox, message);
+
+ return save(mailbox, message);
+ }
+
+ @Override
+ public Iterator<UpdatedFlags> updateFlags(Mailbox mailbox, FlagsUpdateCalculator flagsUpdateCalculator,
+ MessageRange set) throws MailboxException {
+ ImmutableList.Builder<UpdatedFlags> updatedFlags = ImmutableList.builder();
+ Iterator<MailboxMessage> messages = findInMailbox(mailbox, set, FetchType.Metadata, -1);
+
+ long modSeq = -1;
+ if (messages.hasNext()) {
+ modSeq = messageMetadataMapper.nextModSeq(mailbox);
+ }
+ while(messages.hasNext()) {
+ MailboxMessage member = messages.next();
+ Flags originalFlags = member.createFlags();
+ member.setFlags(flagsUpdateCalculator.buildNewFlags(originalFlags));
+ Flags newFlags = member.createFlags();
+ if (UpdatedFlags.flagsChanged(originalFlags, newFlags)) {
+ member.setModSeq(modSeq);
+ save(mailbox, member);
+ }
+
+ UpdatedFlags uFlags = new UpdatedFlags(member.getUid(), member.getModSeq(), originalFlags, newFlags);
+
+ updatedFlags.add(uFlags);
+
+ }
+
+ return updatedFlags.build().iterator();
+ }
+
+ @Override
+ public MessageMetaData copy(Mailbox mailbox, MailboxMessage original) throws MailboxException {
+ return copy(mailbox, messageMetadataMapper.nextUid(mailbox), messageMetadataMapper.nextModSeq(mailbox), original);
+ }
+
+ @Override
+ public Optional<MessageUid> getLastUid(Mailbox mailbox) throws MailboxException {
+ return messageMetadataMapper.getLastUid(mailbox);
+ }
+
+ @Override
+ public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+ return messageMetadataMapper.getHighestModSeq(mailbox);
+ }
+
+ private MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
throws MailboxException {
MailboxMessage copy;
+ JPAMailbox currentMailbox;
+ if (mailbox instanceof JPAMailbox) {
+ currentMailbox = (JPAMailbox) mailbox;
+ } else {
+ currentMailbox = new JPAMailbox(mailbox);
+ }
if (original instanceof JPAStreamingMailboxMessage) {
- copy = new JPAStreamingMailboxMessage((JPAMailbox) mailbox, uid, modSeq, original);
+ copy = new JPAStreamingMailboxMessage(currentMailbox, uid, modSeq, original);
} else if (original instanceof JPAEncryptedMailboxMessage) {
- copy = new JPAEncryptedMailboxMessage((JPAMailbox) mailbox, uid, modSeq, original);
+ copy = new JPAEncryptedMailboxMessage(currentMailbox, uid, modSeq, original);
} else {
- copy = new JPAMailboxMessage((JPAMailbox) mailbox, uid, modSeq, original);
+ copy = new JPAMailboxMessage(currentMailbox, uid, modSeq, original);
}
return save(mailbox, copy);
}
@@ -303,19 +314,25 @@ public class JPAMessageMapper extends AbstractMessageMapper implements MessageMa
* MailboxMessage)
*/
protected MessageMetaData save(Mailbox mailbox, MailboxMessage message) throws MailboxException {
-
try {
-
// We need to reload a "JPA attached" mailbox, because the provide
// mailbox is already "JPA detached"
// If we don't this, we will get an
// org.apache.openjpa.persistence.ArgumentException.
JPAId mailboxId = (JPAId) mailbox.getMailboxId();
- ((AbstractJPAMailboxMessage) message)
- .setMailbox(getEntityManager().find(JPAMailbox.class, mailboxId.getRawId()));
+ JPAMailbox currentMailbox = getEntityManager().find(JPAMailbox.class, mailboxId.getRawId());
+ if (message instanceof AbstractJPAMailboxMessage) {
+ ((AbstractJPAMailboxMessage) message).setMailbox(currentMailbox);
+
+ getEntityManager().persist(message);
+ return new SimpleMessageMetaData(message);
+ } else {
+ JPAMailboxMessage persistData = new JPAMailboxMessage(currentMailbox, message.getUid(), message.getModSeq(), message);
+ persistData.setFlags(new Flags());
+ getEntityManager().persist(persistData);
+ return new SimpleMessageMetaData(persistData);
+ }
- getEntityManager().persist(message);
- return new SimpleMessageMetaData(message);
} catch (PersistenceException e) {
throw new MailboxException("Save of message " + message + " failed in mailbox " + mailbox, e);
} catch (ArgumentException e) {
http://git-wip-us.apache.org/repos/asf/james-project/blob/a377d438/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMetadata.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMetadata.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMetadata.java
new file mode 100644
index 0000000..1907cf0
--- /dev/null
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMetadata.java
@@ -0,0 +1,69 @@
+/****************************************************************
+ * 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.mail;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+
+import com.google.common.base.Optional;
+
+public class MessageMetadata {
+ private final MailboxSession mailboxSession;
+ private final UidProvider uidProvider;
+ private final ModSeqProvider modSeqProvider;
+
+ public MessageMetadata(MailboxSession mailboxSession, UidProvider uidProvider, ModSeqProvider modSeqProvider) {
+ this.mailboxSession = mailboxSession;
+ this.uidProvider = uidProvider;
+ this.modSeqProvider = modSeqProvider;
+ }
+
+ public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+ return modSeqProvider.highestModSeq(mailboxSession, mailbox);
+ }
+
+ public Optional<MessageUid> getLastUid(Mailbox mailbox) throws MailboxException {
+ return uidProvider.lastUid(mailboxSession, mailbox);
+ }
+
+
+ public MessageUid nextUid(Mailbox mailbox) throws MailboxException {
+ return uidProvider.nextUid(mailboxSession, mailbox);
+ }
+
+ public long nextModSeq(Mailbox mailbox) throws MailboxException {
+ if (modSeqProvider != null) {
+ return modSeqProvider.nextModSeq(mailboxSession, mailbox);
+ }
+ return -1;
+ }
+
+ public void enrichMessage(Mailbox mailbox, MailboxMessage message) throws MailboxException {
+ message.setUid(nextUid(mailbox));
+
+ if (modSeqProvider != null) {
+ message.setModSeq(nextModSeq(mailbox));
+ }
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org