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 no...@apache.org on 2010/05/12 18:50:27 UTC
svn commit: r943579 [1/2] - in /james/imap/trunk:
deployment/src/test/java/org/apache/james/imap/functional/jcr/
jcr/src/main/java/org/apache/james/imap/jcr/
jcr/src/main/java/org/apache/james/imap/jcr/mail/
jcr/src/main/java/org/apache/james/imap/jcr/...
Author: norman
Date: Wed May 12 16:50:26 2010
New Revision: 943579
URL: http://svn.apache.org/viewvc?rev=943579&view=rev
Log:
* Introduce a UidConsumer which take care of consume/reserve the next uid for the message to append. Every implementation need to write a specific implementation
* Refactor the implementations to use the UidConsumer
* Now the JCRStressTest passes
* Relayout the JCR Tree (still work in progress) to make it more usable when using webdav etc
Added:
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAUidConsumer.java
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/UidConsumer.java
Removed:
james/imap/trunk/jcr/src/test/java/org/apache/james/imap/jcr/JCRUtilsTest.java
Modified:
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailbox.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRSubscriptionManager.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUtils.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMailbox.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMessage.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java
james/imap/trunk/jcr/src/main/resources/org/apache/james/imap/jcr/imap.cnd
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailboxManager.java
Modified: james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java (original)
+++ james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java Wed May 12 16:50:26 2010
@@ -28,7 +28,6 @@ import org.apache.james.imap.encode.main
import org.apache.james.imap.functional.ImapHostSystem;
import org.apache.james.imap.functional.InMemoryUserManager;
import org.apache.james.imap.jcr.GlobalMailboxSessionJCRRepository;
-import org.apache.james.imap.jcr.JCRImapConstants;
import org.apache.james.imap.jcr.JCRMailboxManager;
import org.apache.james.imap.jcr.JCRSubscriptionManager;
import org.apache.james.imap.jcr.JCRUtils;
@@ -70,7 +69,7 @@ public class JCRHostSystem extends ImapH
userManager = new InMemoryUserManager();
//TODO: Fix the scaling stuff so the tests will pass with max scaling too
- mailboxManager = new JCRMailboxManager(userManager, new JCRSubscriptionManager(sessionRepos, JCRImapConstants.MIN_SCALING), sessionRepos, JCRImapConstants.MIN_SCALING);
+ mailboxManager = new JCRMailboxManager(userManager, new JCRSubscriptionManager(sessionRepos), sessionRepos);
final DefaultImapProcessorFactory defaultImapProcessorFactory = new DefaultImapProcessorFactory();
resetUserMetaData();
Modified: james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java (original)
+++ james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java Wed May 12 16:50:26 2010
@@ -26,10 +26,11 @@ import org.apache.commons.logging.impl.S
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.apache.james.imap.functional.AbstractStressTest;
-import org.apache.james.imap.jcr.JCRImapConstants;
+import org.apache.james.imap.jcr.GlobalMailboxSessionJCRRepository;
import org.apache.james.imap.jcr.JCRMailboxManager;
+import org.apache.james.imap.jcr.JCRSubscriptionManager;
import org.apache.james.imap.jcr.JCRUtils;
-import org.apache.james.imap.mailbox.MailboxException;
+import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.store.StoreMailboxManager;
import org.junit.After;
@@ -64,35 +65,35 @@ public class JCRStressTest extends Abstr
// Register imap cnd file
JCRUtils.registerCnd(repository, workspace, user, pass);
+ MailboxSessionJCRRepository sessionRepos = new GlobalMailboxSessionJCRRepository(repository, workspace, user, pass);
// TODO: Fix the scaling stuff so the tests will pass with max scaling
// too
- //mailboxManager = new JCRGlobalUserMailboxManager(null, new JCRGlobalUserSubscriptionManager(repository, workspace, user, pass, JCRImapConstants.MIN_SCALING), repository, workspace, user, pass, JCRImapConstants.MIN_SCALING);
+ mailboxManager = new JCRMailboxManager(null, new JCRSubscriptionManager(sessionRepos), sessionRepos);
}
- /*
+
@After
public void tearDown() {
MailboxSession session = mailboxManager.createSystemSession("test", new SimpleLog("Test"));
+ /*
try {
//mailboxManager.deleteEverything(session);
} catch (MailboxException e) {
e.printStackTrace();
}
+ */
session.close();
new File(JACKRABBIT_HOME).delete();
}
-*/
+
@Override
protected StoreMailboxManager<?> getMailboxManager() {
return mailboxManager;
}
- @Override
- public void testStessTest() throws InterruptedException, MailboxException {
- //
- }
+
}
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java Wed May 12 16:50:26 2010
@@ -21,6 +21,7 @@ package org.apache.james.imap.jcr;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import org.apache.commons.logging.Log;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.mailbox.MailboxException;
import org.apache.james.imap.store.transaction.AbstractTransactionalMapper;
@@ -30,21 +31,29 @@ import org.apache.james.imap.store.trans
/**
* Abstract Mapper base class for Level 1 Implementations of JCR. So no real transaction management is used.
*
- * The Session.save() will get called on commit() method
+ * The Session.save() will get called on commit() method, session.refresh(false) on rollback, and session.refresh(true) on begin()
*
*/
public abstract class AbstractJCRMapper extends AbstractTransactionalMapper implements JCRImapConstants{
+ public final static String MAILBOXES_PATH = "mailboxes";
+ public final static String SUBSCRIPTIONS_PATH = "subscriptions";
private final Session session;
- private final int scaling;
+ private final Log logger;
- public AbstractJCRMapper(final Session session, final int scaling) {
+ public AbstractJCRMapper(final Session session, Log logger) {
this.session = session;
- this.scaling = scaling;
+ this.logger = logger;
}
- protected int getScaling() {
- return scaling;
+
+ /**
+ * Return the logger
+ *
+ * @return logger
+ */
+ protected Log getLogger() {
+ return logger;
}
/**
@@ -56,19 +65,18 @@ public abstract class AbstractJCRMapper
return session;
}
- /*
- * (non-Javadoc)
- * @see org.apache.james.imap.store.transaction.TransactionalMapper#destroy()
- */
- public void destroy() {
- // Do nothing
- }
/**
- * Begin is not supported by level 1 JCR implementations, so just do nothing
+ * Begin is not supported by level 1 JCR implementations, however we refresh the session
*/
- protected void begin() throws MailboxException {
+ protected void begin() throws MailboxException {
+ try {
+ session.refresh(true);
+ } catch (RepositoryException e) {
+ // do nothin on refresh
+ }
// Do nothing
+
}
/**
@@ -80,8 +88,7 @@ public abstract class AbstractJCRMapper
session.save();
}
} catch (RepositoryException e) {
- e.printStackTrace();
- throw new MailboxException(HumanReadableText.SAVE_FAILED, e);
+ throw new MailboxException(HumanReadableText.COMMIT_TRANSACTION_FAILED, e);
}
}
@@ -90,12 +97,12 @@ public abstract class AbstractJCRMapper
* Rollback is not supported by level 1 JCR implementations, so just do nothing
*/
protected void rollback() throws MailboxException {
- // no rollback supported by level 1 jcr
- }
-
- public void dispose() {
- session.logout();
+ try {
+ // just refresh session and discard all pending changes
+ session.refresh(false);
+ } catch (RepositoryException e) {
+ // just catch on rollback by now
+ }
}
-
-
+
}
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailbox.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailbox.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailbox.java Wed May 12 16:50:26 2010
@@ -35,13 +35,11 @@ import org.apache.james.imap.mailbox.Mai
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.mailbox.util.MailboxEventDispatcher;
import org.apache.james.imap.store.StoreMailbox;
-import org.apache.james.imap.store.mail.MailboxMapper;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.MessageMapper;
import org.apache.james.imap.store.mail.model.Header;
-import org.apache.james.imap.store.mail.model.Mailbox;
import org.apache.james.imap.store.mail.model.MailboxMembership;
import org.apache.james.imap.store.mail.model.PropertyBuilder;
-import org.apache.james.imap.store.transaction.TransactionalMapper;
/**
* JCR implementation of a {@link StoreMailbox}
@@ -51,27 +49,15 @@ public class JCRMailbox extends StoreMai
private final Session jcrSession;
private final Log log;
- private final int scaling;
- public JCRMailbox(final MailboxEventDispatcher dispatcher, final org.apache.james.imap.jcr.mail.model.JCRMailbox mailbox, final Session jcrSession, final int scaling, final Log log) {
- super(dispatcher, mailbox);
+ public JCRMailbox(final MailboxEventDispatcher dispatcher, UidConsumer<String> consumer, final org.apache.james.imap.jcr.mail.model.JCRMailbox mailbox, final Session jcrSession, final Log log) {
+ super(dispatcher, consumer, mailbox);
this.log = log;
- this.scaling = scaling;
this.jcrSession = jcrSession;
}
- /**
- * Return the scaling depth
- *
- * @return scaling
- */
- protected int getScaling() {
- return scaling;
- }
-
-
@Override
protected MailboxMembership<String> copyMessage(MailboxMembership<String> originalMessage, long uid, MailboxSession session) throws MailboxException {
MailboxMembership<String> newRow = new JCRMailboxMembership(getMailboxId(), uid, (JCRMailboxMembership) originalMessage, log);
@@ -97,7 +83,7 @@ public class JCRMailbox extends StoreMai
@Override
protected MessageMapper<String> createMessageMapper(MailboxSession session) throws MailboxException {
- JCRMessageMapper messageMapper = new JCRMessageMapper(jcrSession, getMailboxId(), getScaling(), log);
+ JCRMessageMapper messageMapper = new JCRMessageMapper(jcrSession, getMailboxId(), log);
return messageMapper;
@@ -112,22 +98,8 @@ public class JCRMailbox extends StoreMai
* @throws MailboxException
*/
protected JCRMailboxMapper createMailboxMapper(MailboxSession session) throws MailboxException {
- JCRMailboxMapper mapper = new JCRMailboxMapper(jcrSession, getScaling(), log);
+ JCRMailboxMapper mapper = new JCRMailboxMapper(jcrSession, log);
return mapper;
}
-
- @Override
- protected Mailbox<String> reserveNextUid(MailboxSession session) throws MailboxException {
- final MailboxMapper<String> mapper = createMailboxMapper(session);
- final org.apache.james.imap.jcr.mail.model.JCRMailbox mailbox = (org.apache.james.imap.jcr.mail.model.JCRMailbox) mapper.findMailboxById(getMailboxId());
- mapper.execute(new TransactionalMapper.Transaction() {
-
- public void run() throws MailboxException {
- mailbox.consumeUid();
- }
-
- });
- return mailbox;
- }
}
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java Wed May 12 16:50:26 2010
@@ -37,6 +37,7 @@ import org.apache.james.imap.store.Passw
import org.apache.james.imap.store.StoreMailbox;
import org.apache.james.imap.store.StoreMailboxManager;
import org.apache.james.imap.store.Subscriber;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.MailboxMapper;
import org.apache.james.imap.store.mail.model.Mailbox;
import org.apache.james.imap.store.transaction.TransactionalMapper;
@@ -50,32 +51,17 @@ public class JCRMailboxManager extends S
private final MailboxSessionJCRRepository repository;
private final Log logger = LogFactory.getLog(JCRMailboxManager.class);
- private final int scaling;
- public JCRMailboxManager(final Authenticator authenticator, final Subscriber subscriber, final MailboxSessionJCRRepository repository, final int scaling) {
- super(authenticator, subscriber);
+ public JCRMailboxManager(final Authenticator authenticator, final Subscriber subscriber, final MailboxSessionJCRRepository repository) {
+ super(authenticator, subscriber, new JCRUidConsumer(repository));
this.repository = repository;
- this.scaling = scaling;
}
-
- public JCRMailboxManager(final Authenticator authenticator, final Subscriber subscriber, final MailboxSessionJCRRepository repository) {
- this(authenticator, subscriber, repository, MIN_SCALING);
- }
-
- /**
- * Return the scaling depth
- *
- * @return scaling
- */
- protected int getScaling() {
- return scaling;
- }
-
+
@Override
- protected StoreMailbox<String> createMailbox(MailboxEventDispatcher dispatcher, Mailbox<String> mailboxRow, MailboxSession session) throws MailboxException{
+ protected StoreMailbox<String> createMailbox(MailboxEventDispatcher dispatcher, UidConsumer<String> consumer,Mailbox<String> mailboxRow, MailboxSession session) throws MailboxException{
try {
- return new JCRMailbox(dispatcher, (org.apache.james.imap.jcr.mail.model.JCRMailbox) mailboxRow, repository.login(session), getScaling(), getLog());
+ return new JCRMailbox(dispatcher, consumer, (org.apache.james.imap.jcr.mail.model.JCRMailbox) mailboxRow, repository.login(session), getLog());
} catch (RepositoryException e) {
throw new MailboxException(HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING, e);
}
@@ -86,7 +72,7 @@ public class JCRMailboxManager extends S
try {
Session jcrSession = repository.login(session);
- JCRMailboxMapper mapper = new JCRMailboxMapper(jcrSession, getScaling(), getLog());
+ JCRMailboxMapper mapper = new JCRMailboxMapper(jcrSession, getLog());
return mapper;
} catch (RepositoryException e) {
throw new MailboxException(HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING, e);
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRSubscriptionManager.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRSubscriptionManager.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRSubscriptionManager.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRSubscriptionManager.java Wed May 12 16:50:26 2010
@@ -40,34 +40,19 @@ import org.apache.james.imap.store.user.
public class JCRSubscriptionManager extends StoreSubscriptionManager implements JCRImapConstants{
private final Log logger = LogFactory.getLog(JCRSubscriptionManager.class);
private final MailboxSessionJCRRepository repository;
- private final int scaling;
- public JCRSubscriptionManager(final MailboxSessionJCRRepository repository, final int scaling) {
+ public JCRSubscriptionManager(final MailboxSessionJCRRepository repository ) {
super();
- this.scaling = scaling;
this.repository = repository;
}
- public JCRSubscriptionManager(final MailboxSessionJCRRepository repository ) {
- this(repository, MIN_SCALING);
- }
-
-
- /**
- * Return the scaling depth
- *
- * @return scaling
- */
- protected int getScaling() {
- return scaling;
- }
@Override
protected SubscriptionMapper createMapper(MailboxSession session) throws SubscriptionException {
try {
Session jcrSession = repository.login(session);
- JCRSubscriptionMapper mapper = new JCRSubscriptionMapper(jcrSession, getScaling(), logger);
+ JCRSubscriptionMapper mapper = new JCRSubscriptionMapper(jcrSession, logger);
return mapper;
} catch (RepositoryException e) {
Added: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java?rev=943579&view=auto
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java (added)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java Wed May 12 16:50:26 2010
@@ -0,0 +1,79 @@
+/****************************************************************
+ * 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.imap.jcr;
+
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.util.Locked;
+import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.jcr.mail.model.JCRMailbox;
+import org.apache.james.imap.mailbox.MailboxException;
+import org.apache.james.imap.mailbox.MailboxSession;
+import org.apache.james.imap.store.UidConsumer;
+import org.apache.james.imap.store.mail.model.Mailbox;
+
+/**
+ * {@link UidConsumer} implementation for JCR. It use the {@link Locked} class to lock the Mailbox Node while
+ * consume the next uid. So we can be sure that its really unique
+ *
+ *
+ */
+public class JCRUidConsumer implements UidConsumer<String>{
+
+ private MailboxSessionJCRRepository repos;
+
+ public JCRUidConsumer(MailboxSessionJCRRepository repos) {
+ this.repos = repos;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.james.imap.store.UidConsumer#reserveNextUid(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.MailboxSession)
+ */
+ public long reserveNextUid(Mailbox<String> mailbox, MailboxSession session) throws MailboxException {
+ try {
+ Session jcrSession = repos.login(session);
+ Node node = jcrSession.getNodeByIdentifier(mailbox.getMailboxId());
+ return (Long) new Locked() {
+
+ @Override
+ protected Object run(Node node) throws RepositoryException {
+ Property uidProp = node.getProperty(JCRMailbox.LASTUID_PROPERTY);
+ long uid = uidProp.getLong();
+ uid++;
+ uidProp.setValue(uid);
+ uidProp.getSession().save();
+ return uid;
+ }
+ }.with(node, false);
+
+
+ } catch (RepositoryException e) {
+ throw new MailboxException(HumanReadableText.COMSUME_UID_FAILED, e);
+ } catch (InterruptedException e) {
+ throw new MailboxException(HumanReadableText.COMSUME_UID_FAILED, e);
+ }
+
+ }
+
+}
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUtils.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUtils.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUtils.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUtils.java Wed May 12 16:50:26 2010
@@ -21,19 +21,11 @@ package org.apache.james.imap.jcr;
import java.io.InputStream;
import java.io.InputStreamReader;
-import javax.jcr.ItemExistsException;
-import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
-import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.version.VersionException;
import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.apache.jackrabbit.util.Text;
/**
* Utilities used for JCR
@@ -41,140 +33,6 @@ import org.apache.jackrabbit.util.Text;
*/
public class JCRUtils implements JCRImapConstants{
-
-
- /**
- * Create a scaled path for the given path, where scaling is the nesting mode.
- * There will be no escaping of illegal chars at this point
- *
- * With scaling -1 it will create a sub-path for every char in the path.
- *
- * So for example:
- *
- * scaling = -1
- * user/test:
- * u/us/use/user/t/te/tes/test
- *
- * scaling = 2
- * user/test:
- * u/us/user/t/te/test
- *
- * scaling = 0
- * user/test:
- * user/test
- *
- *
- * @param path
- * @param scaling
- * @return scaledPath
- */
- public static String createScaledPath(String path, int scaling) {
- if (scaling == MIN_SCALING) {
- return path;
- } else {
- StringBuffer buffer = new StringBuffer();
- String[] pathParts = path.split(NODE_DELIMITER);
-
- for (int a = 0; a < pathParts.length; a++) {
- String subPath =escape(pathParts[a]);
-
- for (int i = 0; i < subPath.length(); i++) {
-
- if ( scaling != MAX_SCALING && i == scaling) {
- buffer.append(subPath);
-
- if (a +1 != pathParts.length) {
- buffer.append(NODE_DELIMITER);
- }
- break;
- } else {
- buffer.append(subPath.substring(0,i +1));
-
- if (i +1 != subPath.length() || a +1 != pathParts.length) {
- buffer.append(NODE_DELIMITER);
- }
- }
- }
- }
- return buffer.toString();
- }
- }
-
- public static String escape(String string) {
- return Text.escapeIllegalJcrChars(string);
- }
-
- public static String createScaledPath(String[] paths, int scaling) {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < paths.length; i++) {
- String path = paths[i];
- sb.append(path);
- if (i + 1 != path.length()) {
- sb.append(NODE_DELIMITER);
- }
- }
- return createScaledPath(sb.toString(), scaling);
- }
-
-
-
- /**
- * Create a node path recursive from the given root {@link Node}. This includes
- * to create all subnodes
- *
- * @param rootNode
- * @param nodePath
- * @return lastNode
- * @throws PathNotFoundException
- * @throws ItemExistsException
- * @throws VersionException
- * @throws ConstraintViolationException
- * @throws LockException
- * @throws RepositoryException
- */
- public static Node createNodeRecursive(Node rootNode, String nodePath) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, LockException, RepositoryException {
- return createNodeRecursive(rootNode, nodePath, null);
- }
-
- public static Node createNodeRecursive(Node rootNode, String nodePath, String primaryNodeTypeName) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, LockException, RepositoryException {
- Node parent = rootNode;
- String nodeNames[] = nodePath.split(NODE_DELIMITER);
- for (int i = 0; i < nodeNames.length; i++) {
- String nodeName = escape(nodeNames[i]);
- if (parent.hasNode(nodeName)) {
- parent = parent.getNode(nodeName);
- } else {
- if (i +1 == nodeNames.length && primaryNodeTypeName != null) {
- parent = parent.addNode(nodeName, primaryNodeTypeName);
- } else {
- parent = parent.addNode(nodeName);
- }
- }
- }
- return parent;
- }
- /**
- * Create a path which can be used for nodes. It handles the escaping etc
- *
- * @param subNodes
- * @return completePath
- */
- public static String escapePath(String... subNodes) {
- StringBuffer pathBuf = new StringBuffer();
-
- for (int i = 0; i < subNodes.length; i++) {
- String path = subNodes[i];
- pathBuf.append(escape(path));
-
- if (i + 1 != subNodes.length) {
- pathBuf.append(NODE_DELIMITER);
- }
- }
- return pathBuf.toString();
- }
-
-
-
/**
* Register the imap CND file in the workspace
*
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java Wed May 12 16:50:26 2010
@@ -31,12 +31,10 @@ import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.apache.commons.logging.Log;
-import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.jcr.AbstractJCRMapper;
-import org.apache.james.imap.jcr.JCRUtils;
import org.apache.james.imap.jcr.mail.model.JCRMailbox;
-import org.apache.james.imap.mailbox.MailboxException;
import org.apache.james.imap.mailbox.MailboxNotFoundException;
import org.apache.james.imap.mailbox.StorageException;
import org.apache.james.imap.store.mail.MailboxMapper;
@@ -49,12 +47,8 @@ import org.apache.james.imap.store.mail.
*/
public class JCRMailboxMapper extends AbstractJCRMapper implements MailboxMapper<String> {
- public final String PATH = "mailboxes";
- private final Log logger;
-
- public JCRMailboxMapper(final Session session, final int scaling,final Log logger) {
- super(session, scaling);
- this.logger = logger;
+ public JCRMailboxMapper(final Session session, final Log logger) {
+ super(session, logger);
}
/*
@@ -65,21 +59,21 @@ public class JCRMailboxMapper extends Ab
* (java.lang.String)
*/
public long countMailboxesWithName(String name) throws StorageException {
-
+
try {
- QueryManager manager = getSession().getWorkspace().getQueryManager();
- String queryString = "//" + PATH + "//element(*,imap:mailbox)[@" + JCRMailbox.NAME_PROPERTY + "='" + name + "']";
- QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
- NodeIterator it = result.getNodes();
- long resultSize = it.getSize();
- if (resultSize == -1) {
- resultSize = 0;
- while (it.hasNext()) {
- it.nextNode();
- resultSize++;
- }
- }
- return resultSize;
+ QueryManager manager = getSession().getWorkspace().getQueryManager();
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailbox)[@" + JCRMailbox.NAME_PROPERTY + "='" + name + "'] order by @"+ JCRMailbox.NAME_PROPERTY;
+ QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
+ NodeIterator it = result.getNodes();
+ long resultSize = it.getSize();
+ if (resultSize == -1) {
+ resultSize = 0;
+ while (it.hasNext()) {
+ it.nextNode();
+ resultSize++;
+ }
+ }
+ return resultSize;
} catch (PathNotFoundException e) {
// not found
} catch (RepositoryException e) {
@@ -113,7 +107,7 @@ public class JCRMailboxMapper extends Ab
*/
public void deleteAll() throws StorageException {
try {
- getSession().getRootNode().getNode(PATH).remove();
+ getSession().getRootNode().getNode(MAILBOXES_PATH).remove();
} catch (PathNotFoundException e) {
// nothing todo
@@ -134,7 +128,7 @@ public class JCRMailboxMapper extends Ab
public boolean existsMailboxStartingWith(String mailboxName) throws StorageException {
try {
QueryManager manager = getSession().getWorkspace().getQueryManager();
- String queryString = "//" + PATH + "//element(*,imap:mailbox)[jcr:like(@" + JCRMailbox.NAME_PROPERTY + ",'" +mailboxName+"%')]";
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailbox)[jcr:like(@" + JCRMailbox.NAME_PROPERTY + ",'" +mailboxName+"%')]";
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator it = result.getNodes();
return it.hasNext();
@@ -150,7 +144,7 @@ public class JCRMailboxMapper extends Ab
*/
public Mailbox<String> findMailboxById(String mailboxId) throws StorageException, MailboxNotFoundException {
try {
- return new JCRMailbox(getSession().getNodeByUUID(mailboxId),logger);
+ return new JCRMailbox(getSession().getNodeByUUID(mailboxId), getLogger());
} catch (PathNotFoundException e) {
throw new MailboxNotFoundException(mailboxId);
} catch (RepositoryException e) {
@@ -168,11 +162,11 @@ public class JCRMailboxMapper extends Ab
public Mailbox<String> findMailboxByName(String name) throws StorageException, MailboxNotFoundException {
try {
QueryManager manager = getSession().getWorkspace().getQueryManager();
- String queryString = "//" + PATH + "//element(*,imap:mailbox)[@" + JCRMailbox.NAME_PROPERTY + "='" + name + "']";
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailbox)[@" + JCRMailbox.NAME_PROPERTY + "='" + name + "']";
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator it = result.getNodes();
if (it.hasNext()) {
- return new JCRMailbox(it.nextNode(), logger);
+ return new JCRMailbox(it.nextNode(), getLogger());
}
throw new MailboxNotFoundException(name);
} catch (PathNotFoundException e) {
@@ -194,11 +188,11 @@ public class JCRMailboxMapper extends Ab
List<Mailbox<String>> mailboxList = new ArrayList<Mailbox<String>>();
try {
QueryManager manager = getSession().getWorkspace().getQueryManager();
- String queryString = "//" + PATH + "//element(*,imap:mailbox)[jcr:like(@" + JCRMailbox.NAME_PROPERTY + ",'%" + name + "%')]";
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailbox)[jcr:like(@" + JCRMailbox.NAME_PROPERTY + ",'%" + name + "%')]";
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator it = result.getNodes();
while (it.hasNext()) {
- mailboxList.add(new JCRMailbox(it.nextNode(), logger));
+ mailboxList.add(new JCRMailbox(it.nextNode(), getLogger()));
}
} catch (PathNotFoundException e) {
// nothing todo
@@ -225,10 +219,8 @@ public class JCRMailboxMapper extends Ab
node = getSession().getNodeByUUID(jcrMailbox.getMailboxId());
}
if (node == null) {
- String nodePath = PATH + NODE_DELIMITER + JCRUtils.createScaledPath(mailbox.getName(), getScaling());
-
- node = JCRUtils.createNodeRecursive(getSession().getRootNode(), nodePath, "imap:mailbox");
- node.addMixin(JcrConstants.MIX_REFERENCEABLE);
+ Node mailboxNode = JcrUtils.getOrAddNode(getSession().getRootNode(), MAILBOXES_PATH);
+ node = JcrUtils.getOrAddNode(mailboxNode, mailbox.getName(), "imap:mailbox");
}
jcrMailbox.merge(node);
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java Wed May 12 16:50:26 2010
@@ -20,6 +20,8 @@ package org.apache.james.imap.jcr.mail;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
import java.util.List;
import javax.jcr.Node;
@@ -32,9 +34,10 @@ import javax.jcr.query.QueryResult;
import org.apache.commons.logging.Log;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.util.Locked;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.jcr.AbstractJCRMapper;
-import org.apache.james.imap.jcr.JCRUtils;
import org.apache.james.imap.jcr.mail.model.JCRMailboxMembership;
import org.apache.james.imap.mailbox.MessageRange;
import org.apache.james.imap.mailbox.SearchQuery;
@@ -47,13 +50,10 @@ import org.apache.james.imap.store.mail.
public class JCRMessageMapper extends AbstractJCRMapper implements MessageMapper<String> {
- private final static String PATH = "mailboxes";
- private final Log logger;
private final String uuid;
- public JCRMessageMapper(final Session session, final String uuid, final int scaling, final Log logger) {
- super(session,scaling);
- this.logger = logger;
+ public JCRMessageMapper(final Session session, final String uuid, final Log logger) {
+ super(session, logger);
this.uuid = uuid;
}
@@ -65,7 +65,8 @@ public class JCRMessageMapper extends Ab
*/
public long countMessagesInMailbox() throws StorageException {
try {
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"']";
+ // we use order by because without it count will always be 0 in jackrabbit
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator nodes = result.getNodes();
@@ -95,7 +96,8 @@ public class JCRMessageMapper extends Ab
public long countUnseenMessagesInMailbox() throws StorageException {
try {
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.SEEN_PROPERTY +"='false']";
+ // we use order by because without it count will always be 0 in jackrabbit
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.SEEN_PROPERTY +"='false'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator nodes = result.getNodes();
@@ -173,42 +175,42 @@ public class JCRMessageMapper extends Ab
private List<MailboxMembership<String>> findMessagesInMailboxAfterUID(String uuid, long uid) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + uid + "] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + uid + "] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
}
private List<MailboxMembership<String>> findMessagesInMailboxWithUID(String uuid, long uid) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + "=" + uid + "] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + "=" + uid + "] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
}
private List<MailboxMembership<String>> findMessagesInMailboxBetweenUIDs(String uuid, long from, long to) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + from + "] AND [@" + JCRMailboxMembership.UID_PROPERTY + "<=" + to + "] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + from + "] AND [@" + JCRMailboxMembership.UID_PROPERTY + "<=" + to + "] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
}
@@ -216,14 +218,13 @@ public class JCRMessageMapper extends Ab
private List<MailboxMembership<String>> findMessagesInMailbox(String uuid) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] order by @" + JCRMailboxMembership.UID_PROPERTY;
- getSession().refresh(true);
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
}
@@ -232,27 +233,27 @@ public class JCRMessageMapper extends Ab
private List<MailboxMembership<String>> findDeletedMessagesInMailboxAfterUID(String uuid, long uid) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + uid + "] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + uid + "] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
}
private List<MailboxMembership<String>> findDeletedMessagesInMailboxWithUID(String uuid, long uid) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + "=" + uid + "] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + "=" + uid + "] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- JCRMailboxMembership member = new JCRMailboxMembership(iterator.nextNode(), logger);
+ JCRMailboxMembership member = new JCRMailboxMembership(iterator.nextNode(), getLogger());
list.add(member);
}
return list;
@@ -260,14 +261,14 @@ public class JCRMessageMapper extends Ab
private List<MailboxMembership<String>> findDeletedMessagesInMailboxBetweenUIDs(String uuid, long from, long to) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + from + "] AND [@" + JCRMailboxMembership.UID_PROPERTY + "<=" + to + "] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY + "='" + uuid + "'] AND [@" + JCRMailboxMembership.UID_PROPERTY + ">=" + from + "] AND [@" + JCRMailboxMembership.UID_PROPERTY + "<=" + to + "] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
}
@@ -275,14 +276,14 @@ public class JCRMessageMapper extends Ab
private List<MailboxMembership<String>> findDeletedMessagesInMailbox(String uuid) throws RepositoryException {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.DELETED_PROPERTY+ "='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
- JCRMailboxMembership member = new JCRMailboxMembership(iterator.nextNode(), logger);
+ JCRMailboxMembership member = new JCRMailboxMembership(iterator.nextNode(), getLogger());
list.add(member);
}
return list;
@@ -334,14 +335,14 @@ public class JCRMessageMapper extends Ab
try {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.RECENT_PROPERTY +"='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.RECENT_PROPERTY +"='true'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while(iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
} catch (RepositoryException e) {
@@ -358,14 +359,14 @@ public class JCRMessageMapper extends Ab
public List<MailboxMembership<String>> findUnseenMessagesInMailbox() throws StorageException {
try {
List<MailboxMembership<String>> list = new ArrayList<MailboxMembership<String>>();
- String queryString = "//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.SEEN_PROPERTY +"='false'] order by @" + JCRMailboxMembership.UID_PROPERTY;
+ String queryString = "//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] AND [@" + JCRMailboxMembership.SEEN_PROPERTY +"='false'] order by @" + JCRMailboxMembership.UID_PROPERTY;
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator iterator = result.getNodes();
while(iterator.hasNext()) {
- list.add(new JCRMailboxMembership(iterator.nextNode(), logger));
+ list.add(new JCRMailboxMembership(iterator.nextNode(), getLogger()));
}
return list;
} catch (RepositoryException e) {
@@ -382,7 +383,7 @@ public class JCRMessageMapper extends Ab
* imap.store.mail.model.MailboxMembership)
*/
public void save(MailboxMembership<String> message) throws StorageException {
- JCRMailboxMembership membership = (JCRMailboxMembership) message;
+ final JCRMailboxMembership membership = (JCRMailboxMembership) message;
try {
//JCRUtils.createNodeRecursive(getSession().getRootNode(), mailboxN);
Node messageNode = null;
@@ -392,30 +393,81 @@ public class JCRMessageMapper extends Ab
}
if (messageNode == null) {
+ Date date = message.getInternalDate();
+ if (date == null) {
+ date = new Date();
+ }
+
+ // extracte the date from the message to create node structure later
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ final String year = String.valueOf(cal.get(Calendar.YEAR));
+ final String month = String.valueOf(cal.get(Calendar.MONTH +1));
+ final String day = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
+
+ Node dayNode = null;
Node mailboxNode = getSession().getNodeByUUID(uuid);
- Node membershipsNode;
+ String dayNodePath = year + NODE_DELIMITER + month + NODE_DELIMITER + day;
+ boolean found = mailboxNode.hasNode(dayNodePath);
- if (mailboxNode.hasNode("mailboxMemberships")) {
- membershipsNode = mailboxNode.getNode("mailboxMemberships");
+ // check if the node for the day already exists. if not we need to create the structure
+ if (found == false) {
+ // we lock the whole mailbox with all its childs while
+ // adding the folder structure for the date
+ // TODO: Maybe we should just lock the last child folder
+ dayNode = (Node) new Locked() {
+
+ @Override
+ protected Object run(Node mailboxNode) throws RepositoryException {
+
+ Node yearNode = JcrUtils.getOrAddFolder(mailboxNode, String.valueOf(year));
+ yearNode.addMixin(JcrConstants.MIX_LOCKABLE);
+
+ Node monthNode = JcrUtils.getOrAddFolder(yearNode, String.valueOf(month));
+ monthNode.addMixin(JcrConstants.MIX_LOCKABLE);
+
+ Node dayNode = JcrUtils.getOrAddFolder(monthNode, String.valueOf(day));
+ dayNode.addMixin(JcrConstants.MIX_LOCKABLE);
+ // save the folders for now
+ getSession().save();
+ return dayNode;
+ }
+ }.with(mailboxNode, true);
} else {
- membershipsNode = mailboxNode.addNode("mailboxMemberships","imap:mailboxMemberships");
+
+ dayNode = mailboxNode.getNode(dayNodePath);
}
- // TODO: Maybe we should use some kind of hashes for scaling here
- String path = membershipsNode.getPath() + NODE_DELIMITER + JCRUtils.escapePath(String.valueOf(membership.getUid()));
- // strip leading /
- path = path.substring(1, path.length());
+ // lock the day node and add the message
+ new Locked() {
+
+ @Override
+ protected Object run(Node dayNode) throws RepositoryException {
+ Node messageNode = dayNode.addNode("message-"+String.valueOf(membership.getUid()),"imap:mailboxMembership");
+ try {
+ membership.merge(messageNode);
+ } catch (IOException e) {
+ throw new RepositoryException("Unable to merge message in to tree", e);
+ }
+ // save the message
+ getSession().save();
+
+ return null;
+ }
+
+ }.with(dayNode,false);
- messageNode = getSession().getRootNode().addNode(path,"imap:mailboxMembership");
- messageNode.addMixin(JcrConstants.MIX_REFERENCEABLE);
+
+ } else {
+ membership.merge(messageNode);
}
- membership.merge(messageNode);
} catch (RepositoryException e) {
- e.printStackTrace();
throw new StorageException(HumanReadableText.SAVE_FAILED, e);
} catch (IOException e) {
throw new StorageException(HumanReadableText.SAVE_FAILED, e);
+ } catch (InterruptedException e) {
+ throw new StorageException(HumanReadableText.SAVE_FAILED, e);
}
}
@@ -437,7 +489,7 @@ public class JCRMessageMapper extends Ab
NodeIterator it = result.getNodes();
while (it.hasNext()) {
- list.add(new JCRMailboxMembership(it.nextNode(), logger));
+ list.add(new JCRMailboxMembership(it.nextNode(), getLogger()));
}
return list;
} catch (RepositoryException e) {
@@ -455,7 +507,7 @@ public class JCRMessageMapper extends Ab
*/
private String formulateXPath(String uuid, SearchQuery query) {
final StringBuilder queryBuilder = new StringBuilder(50);
- queryBuilder.append("//" + PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] ");
+ queryBuilder.append("//" + MAILBOXES_PATH + "//element(*,imap:mailboxMembership)[@" + JCRMailboxMembership.MAILBOX_UUID_PROPERTY +"='" + uuid +"'] ");
final List<Criterion> criteria = query.getCriterias();
if (criteria.size() == 1) {
final Criterion firstCriterion = criteria.get(0);
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMailbox.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMailbox.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMailbox.java Wed May 12 16:50:26 2010
@@ -64,6 +64,9 @@ public class JCRMailbox implements Mailb
this.logger = logger;
}
+ public Log getLog() {
+ return logger;
+ }
/*
* (non-Javadoc)
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMessage.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMessage.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMessage.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/model/JCRMessage.java Wed May 12 16:50:26 2010
@@ -30,8 +30,8 @@ import javax.jcr.RepositoryException;
import org.apache.commons.logging.Log;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.util.Text;
import org.apache.james.imap.jcr.JCRImapConstants;
-import org.apache.james.imap.jcr.JCRUtils;
import org.apache.james.imap.jcr.Persistent;
import org.apache.james.imap.store.StreamUtils;
import org.apache.james.imap.store.mail.model.AbstractDocument;
@@ -333,7 +333,7 @@ public class JCRMessage extends Abstract
// store new properties
for (int i = 0; i < newProperites.size(); i++) {
JCRProperty prop = (JCRProperty)newProperites.get(i);
- Node propNode = propertiesNode.addNode(JCRUtils.escapePath(String.valueOf(prop.getOrder())), "imap:messageProperty");
+ Node propNode = propertiesNode.addNode(Text.escapeIllegalJcrChars(String.valueOf(prop.getOrder())), "imap:messageProperty");
prop.merge(propNode);
}
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java Wed May 12 16:50:26 2010
@@ -31,9 +31,9 @@ import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.apache.commons.logging.Log;
+import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.jcr.AbstractJCRMapper;
-import org.apache.james.imap.jcr.JCRUtils;
import org.apache.james.imap.jcr.user.model.JCRSubscription;
import org.apache.james.imap.mailbox.SubscriptionException;
import org.apache.james.imap.store.user.SubscriptionMapper;
@@ -45,12 +45,8 @@ import org.apache.james.imap.store.user.
*/
public class JCRSubscriptionMapper extends AbstractJCRMapper implements SubscriptionMapper {
- private final Log log;
- private final static String PATH = "subscriptions";
-
- public JCRSubscriptionMapper(final Session session, final int scaling,final Log log) {
- super(session, scaling);
- this.log = log;
+ public JCRSubscriptionMapper(final Session session, final Log log) {
+ super(session, log);
}
/*
@@ -85,14 +81,14 @@ public class JCRSubscriptionMapper exten
*/
public Subscription findFindMailboxSubscriptionForUser(String user, String mailbox) throws SubscriptionException {
try {
- String queryString = "//" + PATH + "//element(*,imap:subscription)[@" + JCRSubscription.USERNAME_PROPERTY + "='" + user + "'] AND [@" + JCRSubscription.MAILBOX_PROPERTY +"='" + mailbox + "']";
+ String queryString = "//" + SUBSCRIPTIONS_PATH + "//element(*,imap:subscription)[@" + JCRSubscription.USERNAME_PROPERTY + "='" + user + "'] AND [@" + JCRSubscription.MAILBOX_PROPERTY +"='" + mailbox + "']";
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator nodeIt = result.getNodes();
if (nodeIt.hasNext()) {
- JCRSubscription sub = new JCRSubscription(nodeIt.nextNode(), log);
+ JCRSubscription sub = new JCRSubscription(nodeIt.nextNode(), getLogger());
return sub;
}
@@ -115,14 +111,14 @@ public class JCRSubscriptionMapper exten
public List<Subscription> findSubscriptionsForUser(String user) throws SubscriptionException {
List<Subscription> subList = new ArrayList<Subscription>();
try {
- String queryString = "//" + PATH + "//element(*,imap:subscription)[@" + JCRSubscription.USERNAME_PROPERTY + "='" + user + "']";
+ String queryString = "//" + SUBSCRIPTIONS_PATH + "//element(*,imap:subscription)[@" + JCRSubscription.USERNAME_PROPERTY + "='" + user + "']";
QueryManager manager = getSession().getWorkspace().getQueryManager();
QueryResult result = manager.createQuery(queryString, Query.XPATH).execute();
NodeIterator nodeIt = result.getNodes();
while (nodeIt.hasNext()) {
- subList.add(new JCRSubscription(nodeIt.nextNode(), log));
+ subList.add(new JCRSubscription(nodeIt.nextNode(), getLogger()));
}
} catch (PathNotFoundException e) {
// Do nothing just return the empty list later
@@ -153,9 +149,10 @@ public class JCRSubscriptionMapper exten
// its a new subscription
if (sub == null) {
- String nodePath = PATH + NODE_DELIMITER + JCRUtils.createScaledPath(new String[] {username, mailbox}, getScaling());
+ Node subscriptionsNode = JcrUtils.getOrAddNode(getSession().getRootNode(), SUBSCRIPTIONS_PATH);
- node = JCRUtils.createNodeRecursive(getSession().getRootNode(), nodePath, "imap:subscription");
+ Node userNode = JcrUtils.getOrAddNode(subscriptionsNode, username);
+ node = JcrUtils.getOrAddNode(userNode, mailbox, "imap:subscription");
} else {
node = sub.getNode();
}
Modified: james/imap/trunk/jcr/src/main/resources/org/apache/james/imap/jcr/imap.cnd
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/resources/org/apache/james/imap/jcr/imap.cnd?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/resources/org/apache/james/imap/jcr/imap.cnd (original)
+++ james/imap/trunk/jcr/src/main/resources/org/apache/james/imap/jcr/imap.cnd Wed May 12 16:50:26 2010
@@ -32,14 +32,13 @@
- imap:propertyValue(STRING) mandatory
- imap:propertyOrder (Long) mandatory
-[imap:message] > mix:referenceable, nt:base
+[imap:message] > mix:referenceable, nt:file
- imap:messageBodyStartOctet (LONG) mandatory
- imap:messageFullContentOctets (LONG) mandatory
- imap:messageTextualLineCount (LONG)
- imap:messageSubType (String) mandatory
+ messageHeaders (imap:messageHeaders)
+ messageProperties (imap:messageProperties)
- + jcr:content (nt:resource) mandatory
[imap:messageHeaders] > nt:unstructured
+ imap:messageHeader multiple
@@ -51,9 +50,10 @@
- imap:mailboxUidValidity (LONG) mandatory
- imap:mailboxName (STRING) mandatory
- imap:mailboxLastUid (LONG) mandatory
- + mailboxMemberships (imap:mailboxMemberships)
+ + *
+
-[imap:mailboxMembership] > mix:referenceable, nt:base
+[imap:mailboxMembership] > mix:referenceable, nt:hierarchyNode
- imap:mailboxUUID (String) mandatory
- imap:uid (LONG) mandatory
- imap:size (LONG) mandatory
@@ -65,7 +65,3 @@
- imap:seen (BOOLEAN) mandatory
- imap:internalDate (DATE) mandatory
+ message (imap:message) mandatory
-
- [imap:mailboxMemberships] > nt:unstructured
- + imap:mailboxMembership multiple
-
Modified: james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java (original)
+++ james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java Wed May 12 16:50:26 2010
@@ -25,8 +25,6 @@ import java.util.List;
import javax.mail.Flags;
import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
-import javax.persistence.LockModeType;
import org.apache.james.imap.jpa.mail.JPAMailboxMapper;
import org.apache.james.imap.jpa.mail.JPAMessageMapper;
@@ -37,6 +35,7 @@ import org.apache.james.imap.mailbox.Mai
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.mailbox.util.MailboxEventDispatcher;
import org.apache.james.imap.store.StoreMailbox;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.MailboxMapper;
import org.apache.james.imap.store.mail.MessageMapper;
import org.apache.james.imap.store.mail.model.Header;
@@ -54,8 +53,8 @@ public class JPAMailbox extends StoreMai
protected final EntityManager manager;
- public JPAMailbox(final MailboxEventDispatcher dispatcher, final Mailbox<Long> mailbox, final EntityManager manager) {
- super(dispatcher, mailbox);
+ public JPAMailbox(final MailboxEventDispatcher dispatcher, final UidConsumer<Long> consumer,final Mailbox<Long> mailbox, final EntityManager manager) {
+ super(dispatcher, consumer, mailbox);
this.manager = manager;
}
@@ -88,26 +87,6 @@ public class JPAMailbox extends StoreMai
return newRow;
}
- /**
- * Reserve next Uid in mailbox and return the mailbox. We use a PESSIMISTIC_WRITE lock here to be sure we don't see any duplicates here when
- * accessing the database with many different threads / connections
- *
- */
- protected Mailbox<Long> reserveNextUid(MailboxSession session) throws MailboxException {
-
- EntityTransaction transaction = manager.getTransaction();
- transaction.begin();
-
- // we need to set a persimistic write lock to be sure we don't get any problems with dirty reads etc
- org.apache.james.imap.jpa.mail.model.JPAMailbox mailbox = manager.find(org.apache.james.imap.jpa.mail.model.JPAMailbox.class, getMailboxId(), LockModeType.PESSIMISTIC_WRITE);
- manager.refresh(mailbox);
- mailbox.consumeUid();
- manager.persist(mailbox);
- manager.flush();
- transaction.commit();
- return mailbox;
-
- }
@Override
protected Header createHeader(int lineNumber, String name, String value) {
Modified: james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java (original)
+++ james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java Wed May 12 16:50:26 2010
@@ -40,7 +40,7 @@ public abstract class JPAMailboxManager
protected final MailboxSessionEntityManagerFactory entityManagerFactory;
public JPAMailboxManager(final Authenticator authenticator, final Subscriber subscriber,
final MailboxSessionEntityManagerFactory entityManagerFactory) {
- super(authenticator, subscriber);
+ super(authenticator, subscriber,new JPAUidConsumer(entityManagerFactory));
this.entityManagerFactory = entityManagerFactory;
}
Added: james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAUidConsumer.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAUidConsumer.java?rev=943579&view=auto
==============================================================================
--- james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAUidConsumer.java (added)
+++ james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAUidConsumer.java Wed May 12 16:50:26 2010
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.imap.jpa;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.LockModeType;
+
+import org.apache.james.imap.mailbox.MailboxSession;
+import org.apache.james.imap.store.UidConsumer;
+import org.apache.james.imap.store.mail.model.Mailbox;
+
+public class JPAUidConsumer implements UidConsumer<Long>{
+
+ private MailboxSessionEntityManagerFactory factory;
+
+ public JPAUidConsumer(MailboxSessionEntityManagerFactory factory) {
+ this.factory = factory;
+ }
+
+ /**
+ *
+ * Reserve next Uid in mailbox and return the mailbox. We use a PESSIMISTIC_WRITE lock here to be sure we don't see any duplicates here when
+ * accessing the database with many different threads / connections
+ *
+ * @see org.apache.james.imap.store.UidConsumer#reserveNextUid(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.MailboxSession)
+ */
+ public long reserveNextUid(Mailbox<Long> mailbox, MailboxSession session) {
+ EntityManager manager = factory.createEntityManager(session);
+ EntityTransaction transaction = manager.getTransaction();
+ transaction.begin();
+
+ // we need to set a persimistic write lock to be sure we don't get any problems with dirty reads etc
+ org.apache.james.imap.jpa.mail.model.JPAMailbox m = manager.find(org.apache.james.imap.jpa.mail.model.JPAMailbox.class, mailbox.getMailboxId(), LockModeType.PESSIMISTIC_WRITE);
+ manager.refresh(m);
+ m.consumeUid();
+ manager.persist(m);
+ manager.flush();
+ transaction.commit();
+ return m.getLastUid();
+ }
+
+}
Modified: james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java (original)
+++ james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java Wed May 12 16:50:26 2010
@@ -34,6 +34,7 @@ import org.apache.james.imap.jpa.mail.mo
import org.apache.james.imap.mailbox.MailboxException;
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.mailbox.util.MailboxEventDispatcher;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.model.Header;
import org.apache.james.imap.store.mail.model.Mailbox;
import org.apache.james.imap.store.mail.model.MailboxMembership;
@@ -47,12 +48,12 @@ public class OpenJPAMailbox extends JPAM
private final boolean useStreaming;
- public OpenJPAMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> mailbox, EntityManager entityManager) {
- this(dispatcher, mailbox, entityManager, false);
+ public OpenJPAMailbox(MailboxEventDispatcher dispatcher, UidConsumer<Long> consumer, Mailbox<Long> mailbox, EntityManager entityManager) {
+ this(dispatcher, consumer, mailbox, entityManager, false);
}
- public OpenJPAMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> mailbox, EntityManager entityManager, final boolean useStreaming) {
- super(dispatcher, mailbox, entityManager);
+ public OpenJPAMailbox(MailboxEventDispatcher dispatcher, UidConsumer<Long> consumer, Mailbox<Long> mailbox, EntityManager entityManager, final boolean useStreaming) {
+ super(dispatcher, consumer, mailbox, entityManager);
this.useStreaming = useStreaming;
}
Modified: james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java (original)
+++ james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java Wed May 12 16:50:26 2010
@@ -27,6 +27,7 @@ import org.apache.james.imap.mailbox.uti
import org.apache.james.imap.store.Authenticator;
import org.apache.james.imap.store.StoreMailbox;
import org.apache.james.imap.store.Subscriber;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.model.Mailbox;
/**
@@ -46,8 +47,8 @@ public class OpenJPAMailboxManager exten
this(authenticator, subscriber, entityManagerFactory, false);
}
- protected StoreMailbox<Long> createMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> mailboxRow, MailboxSession session) {
- StoreMailbox<Long> result = new OpenJPAMailbox(dispatcher,mailboxRow, entityManagerFactory.createEntityManager(session), useStreaming);
+ protected StoreMailbox<Long> createMailbox(MailboxEventDispatcher dispatcher, UidConsumer<Long> consumer, Mailbox<Long> mailboxRow, MailboxSession session) {
+ StoreMailbox<Long> result = new OpenJPAMailbox(dispatcher, consumer, mailboxRow,entityManagerFactory.createEntityManager(session), useStreaming);
return result;
}
}
Modified: james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java (original)
+++ james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java Wed May 12 16:50:26 2010
@@ -33,11 +33,12 @@ import org.apache.james.imap.store.Authe
import org.apache.james.imap.store.StoreMailbox;
import org.apache.james.imap.store.StoreMailboxManager;
import org.apache.james.imap.store.Subscriber;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.MailboxMapper;
import org.apache.james.imap.store.mail.model.Mailbox;
import org.apache.james.imap.store.transaction.TransactionalMapper;
-public class InMemoryMailboxManager extends StoreMailboxManager<Long> implements MailboxMapper<Long> {
+public class InMemoryMailboxManager extends StoreMailboxManager<Long> implements MailboxMapper<Long>{
private static final int INITIAL_SIZE = 128;
private Map<Long, InMemoryMailbox> mailboxesById;
@@ -46,17 +47,23 @@ public class InMemoryMailboxManager exte
private MailboxSession session;
public InMemoryMailboxManager(Authenticator authenticator, Subscriber subscriber) {
- super(authenticator, subscriber);
+ super(authenticator, subscriber, new UidConsumer<Long>() {
+
+ public long reserveNextUid(Mailbox<Long> mailbox, MailboxSession session) throws MailboxException {
+ mailbox.consumeUid();
+ return mailbox.getLastUid();
+ }
+ });
mailboxesById = new ConcurrentHashMap<Long, InMemoryMailbox>(INITIAL_SIZE);
storeMailboxByName = new ConcurrentHashMap<String, InMemoryStoreMailbox>(INITIAL_SIZE);
idNameMap = new ConcurrentHashMap<Long, String>(INITIAL_SIZE);
}
@Override
- protected StoreMailbox<Long> createMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> mailboxRow, MailboxSession session) {
+ protected StoreMailbox<Long> createMailbox(MailboxEventDispatcher dispatcher, UidConsumer<Long> consumer, Mailbox<Long> mailboxRow, MailboxSession session) {
InMemoryStoreMailbox storeMailbox = storeMailboxByName.get(mailboxRow.getName());
if (storeMailbox == null) {
- storeMailbox = new InMemoryStoreMailbox(dispatcher, (InMemoryMailbox)mailboxRow);
+ storeMailbox = new InMemoryStoreMailbox(dispatcher, consumer, (InMemoryMailbox)mailboxRow);
storeMailboxByName.put(mailboxRow.getName(), storeMailbox);
}
@@ -209,5 +216,10 @@ public class InMemoryMailboxManager exte
idNameMap.clear();
}
+ public long reserveNextUid(Mailbox<Long> mailbox, MailboxSession session) throws MailboxException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
}
Modified: james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java (original)
+++ james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java Wed May 12 16:50:26 2010
@@ -39,6 +39,7 @@ import org.apache.james.imap.mailbox.Sto
import org.apache.james.imap.mailbox.util.MailboxEventDispatcher;
import org.apache.james.imap.store.MailboxMembershipComparator;
import org.apache.james.imap.store.StoreMailbox;
+import org.apache.james.imap.store.UidConsumer;
import org.apache.james.imap.store.mail.MailboxMapper;
import org.apache.james.imap.store.mail.MessageMapper;
import org.apache.james.imap.store.mail.model.Header;
@@ -52,8 +53,8 @@ public class InMemoryStoreMailbox extend
private Map<Long, MailboxMembership<Long>> membershipByUid;
private InMemoryMailbox mailbox;
- public InMemoryStoreMailbox(MailboxEventDispatcher dispatcher, InMemoryMailbox mailbox) {
- super(dispatcher, mailbox);
+ public InMemoryStoreMailbox(MailboxEventDispatcher dispatcher, UidConsumer<Long> consumer, InMemoryMailbox mailbox) {
+ super(dispatcher, consumer, mailbox);
this.mailbox = mailbox;
this.membershipByUid = new ConcurrentHashMap<Long, MailboxMembership<Long>>(INITIAL_SIZE);
}
@@ -97,14 +98,6 @@ public class InMemoryStoreMailbox extend
protected MessageMapper<Long> createMessageMapper(MailboxSession session) {
return this;
}
-
-
- @Override
- protected Mailbox<Long> reserveNextUid(MailboxSession session) throws MailboxException {
- mailbox.consumeUid();
- return mailbox;
- }
-
/*
* (non-Javadoc)
* @see org.apache.james.imap.store.mail.MessageMapper#countMessagesInMailbox()
Modified: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java?rev=943579&r1=943578&r2=943579&view=diff
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java (original)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java Wed May 12 16:50:26 2010
@@ -83,11 +83,14 @@ public abstract class StoreMailbox<Id> i
private final Id mailboxId;
private MailboxEventDispatcher dispatcher;
+
+ private UidConsumer<Id> consumer;
- public StoreMailbox(final MailboxEventDispatcher dispatcher, final Mailbox<Id> mailbox) {
+ public StoreMailbox(final MailboxEventDispatcher dispatcher, UidConsumer<Id> consumer, final Mailbox<Id> mailbox) {
this.mailboxId = mailbox.getMailboxId();
this.dispatcher = dispatcher;
+ this.consumer = consumer;
}
/**
@@ -157,8 +160,7 @@ public abstract class StoreMailbox<Id> i
// this will hold the uid after the transaction was complete
final MessageMapper<Id> mapper = createMessageMapper(mailboxSession);
- final Mailbox<Id> mailbox = reserveNextUid(mailboxSession);
- final long uid = mailbox.getLastUid();
+ final long uid = consumer.reserveNextUid(getMailboxRow(mailboxSession), mailboxSession);
File file = null;
@@ -379,16 +381,6 @@ public abstract class StoreMailbox<Id> i
protected abstract Header createHeader(int lineNumber, String name, String value);
- /**
- * Reserve the next Uid on the underlying {@link Mailbox}. Its important that the implementation guaranteer a thread-safe/atomic calculation of the
- * next uid. So be sure you don't use any caching etc.
- *
- *
- * @return mailbox
- * @throws MailboxException
- */
- protected abstract Mailbox<Id> reserveNextUid(MailboxSession session) throws MailboxException;
-
/*
* (non-Javadoc)
* @see org.apache.james.imap.mailbox.Mailbox#getMessages(org.apache.james.imap.mailbox.MessageRange, org.apache.james.imap.mailbox.MessageResult.FetchGroup, org.apache.james.imap.mailbox.MailboxSession)
@@ -623,8 +615,7 @@ public abstract class StoreMailbox<Id> i
for (final MailboxMembership<Id> originalMessage:originalRows) {
- final Mailbox<Id> mailbox = reserveNextUid(session );
- final long uid = mailbox.getLastUid();
+ final long uid = consumer.reserveNextUid(getMailboxRow(session),session);
mapper.execute(new TransactionalMapper.Transaction() {
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org