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/06/06 12:00:15 UTC
svn commit: r951847 - 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/user/
Author: norman
Date: Sun Jun 6 10:00:14 2010
New Revision: 951847
URL: http://svn.apache.org/viewvc?rev=951847&view=rev
Log:
Make it easy to implement own Node Locking mechanism (IMAP-149)
Added:
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.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/JCRMailboxManager.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.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/user/JCRSubscriptionMapper.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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -32,11 +32,10 @@ import org.apache.james.imap.jcr.JCRMail
import org.apache.james.imap.jcr.JCRMailboxSessionMapperFactory;
import org.apache.james.imap.jcr.JCRSubscriptionManager;
import org.apache.james.imap.jcr.JCRUtils;
+import org.apache.james.imap.jcr.JCRVmNodeLocker;
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.main.DefaultImapDecoderFactory;
import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
-import org.apache.james.imap.store.Authenticator;
-import org.apache.james.imap.store.Subscriber;
import org.apache.james.test.functional.HostSystem;
import org.xml.sax.InputSource;
@@ -70,7 +69,7 @@ public class JCRHostSystem extends ImapH
JCRUtils.registerCnd(repository, workspace, user, pass);
userManager = new InMemoryUserManager();
- JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos);
+ JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos, new JCRVmNodeLocker());
//TODO: Fix the scaling stuff so the tests will pass with max scaling too
mailboxManager = new JCRMailboxManager(mf, userManager, new JCRSubscriptionManager(mf));
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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -31,6 +31,7 @@ import org.apache.james.imap.jcr.JCRMail
import org.apache.james.imap.jcr.JCRMailboxSessionMapperFactory;
import org.apache.james.imap.jcr.JCRSubscriptionManager;
import org.apache.james.imap.jcr.JCRUtils;
+import org.apache.james.imap.jcr.JCRVmNodeLocker;
import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.store.StoreMailboxManager;
@@ -62,7 +63,7 @@ public class JCRStressTest extends Abstr
JCRUtils.registerCnd(repository, workspace, user, pass);
MailboxSessionJCRRepository sessionRepos = new GlobalMailboxSessionJCRRepository(repository, workspace, user, pass);
- JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos);
+ JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos, new JCRVmNodeLocker());
mailboxManager = new JCRMailboxManager(mf, null, new JCRSubscriptionManager(mf));
}
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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -41,13 +41,19 @@ public abstract class AbstractJCRMapper
private final Log logger;
private final MailboxSessionJCRRepository repository;
private final MailboxSession mSession;
+ private final NodeLocker locker;
- public AbstractJCRMapper(final MailboxSessionJCRRepository repository, MailboxSession mSession, Log logger) {
+ public AbstractJCRMapper(final MailboxSessionJCRRepository repository, MailboxSession mSession, NodeLocker locker, Log logger) {
this.repository = repository;
this.mSession = mSession;
this.logger = logger;
+ this.locker = locker;
}
+ public NodeLocker getNodeLocker() {
+ return locker;
+ }
+
/**
* Return the logger
*
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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -40,15 +40,19 @@ import org.apache.james.imap.store.trans
*/
public class JCRMailboxManager extends StoreMailboxManager<String> implements JCRImapConstants{
- private final JCRMailboxSessionMapperFactory mapperFactory;
- private final Log logger = LogFactory.getLog(JCRMailboxManager.class);
+ private final JCRMailboxSessionMapperFactory mapperFactory;
+ private final Log logger = LogFactory.getLog(JCRMailboxManager.class);
public JCRMailboxManager(JCRMailboxSessionMapperFactory mapperFactory, final Authenticator authenticator, final Subscriber subscriber) {
- super(mapperFactory, authenticator, subscriber, new JCRUidConsumer(mapperFactory.getRepository()));
- this.mapperFactory = mapperFactory;
+ this(mapperFactory, authenticator, subscriber, new JCRVmNodeLocker());
}
+ public JCRMailboxManager(JCRMailboxSessionMapperFactory mapperFactory, final Authenticator authenticator, final Subscriber subscriber, final NodeLocker locker) {
+ super(mapperFactory, authenticator, subscriber, new JCRUidConsumer(mapperFactory.getRepository(), locker));
+ this.mapperFactory = mapperFactory;
+ }
+
@Override
protected StoreMessageManager<String> createMessageManager(MailboxEventDispatcher dispatcher, UidConsumer<String> consumer, Mailbox<String> mailboxEntity, MailboxSession session) throws MailboxException{
return new JCRMessageManager(mapperFactory, dispatcher, consumer, (JCRMailbox) mailboxEntity, logger, getDelimiter(), session);
Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java Sun Jun 6 10:00:14 2010
@@ -42,28 +42,30 @@ public class JCRMailboxSessionMapperFact
private MailboxSessionJCRRepository repository;
private Log logger;
private char delimiter;
+ private NodeLocker locker;
- public JCRMailboxSessionMapperFactory(final MailboxSessionJCRRepository repository) {
+ public JCRMailboxSessionMapperFactory(final MailboxSessionJCRRepository repository, final NodeLocker locker) {
this.repository = repository;
this.logger = LogFactory.getLog(JCRSubscriptionManager.class);
this.delimiter = '.';
+ this.locker = locker;;
}
@Override
public MailboxMapper<String> createMailboxMapper(MailboxSession session) throws MailboxException {
- JCRMailboxMapper mapper = new JCRMailboxMapper(repository, session, logger, delimiter);
+ JCRMailboxMapper mapper = new JCRMailboxMapper(repository, session, locker, logger, delimiter);
return mapper;
}
@Override
public MessageMapper<String> createMessageMapper(MailboxSession session) throws MailboxException {
- JCRMessageMapper messageMapper = new JCRMessageMapper(repository, session, logger);
+ JCRMessageMapper messageMapper = new JCRMessageMapper(repository, session, locker, logger);
return messageMapper;
}
@Override
public SubscriptionMapper createSubscriptionMapper(MailboxSession session) throws SubscriptionException {
- JCRSubscriptionMapper mapper = new JCRSubscriptionMapper(repository, session, logger);
+ JCRSubscriptionMapper mapper = new JCRSubscriptionMapper(repository, session, locker, logger);
return mapper;
}
Modified: 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=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java Sun Jun 6 10:00:14 2010
@@ -41,9 +41,11 @@ import org.apache.james.imap.store.mail.
public class JCRUidConsumer implements UidConsumer<String>{
private MailboxSessionJCRRepository repos;
+ private NodeLocker locker;
- public JCRUidConsumer(MailboxSessionJCRRepository repos) {
+ public JCRUidConsumer(MailboxSessionJCRRepository repos, NodeLocker locker) {
this.repos = repos;
+ this.locker = locker;
}
/*
@@ -54,10 +56,9 @@ public class JCRUidConsumer implements U
try {
Session jcrSession = repos.login(session);
Node node = jcrSession.getNodeByIdentifier(mailbox.getMailboxId());
- return (Long) new Locked() {
-
- @Override
- protected Object run(Node node) throws RepositoryException {
+ long result = locker.execute(new NodeLocker.NodeLockedExecution<Long>() {
+
+ public Long execute(Node node) throws RepositoryException {
Property uidProp = node.getProperty(JCRMailbox.LASTUID_PROPERTY);
long uid = uidProp.getLong();
uid++;
@@ -65,7 +66,13 @@ public class JCRUidConsumer implements U
uidProp.getSession().save();
return uid;
}
- }.with(node, false);
+
+ public boolean isDeepLocked() {
+ return true;
+ }
+
+ }, node, Long.class);
+ return result;
} catch (RepositoryException e) {
Added: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java?rev=951847&view=auto
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java (added)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java Sun Jun 6 10:00:14 2010
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.RepositoryException;
+
+import org.apache.jackrabbit.util.Locked;
+
+/**
+ * {@link NodeLocker} implementation which use {@link Locked} utility to make sure the given node will not get modified while
+ * excecute the {@link NodeLockedExecution}.
+ *
+ * This implementation will only work with NON-CLUSTERED JCR.
+ *
+ */
+public class JCRVmNodeLocker implements NodeLocker{
+
+ @SuppressWarnings("unchecked")
+ public <T> T execute(final NodeLockedExecution<T> exection, Node node, Class<T> returnType) throws RepositoryException, InterruptedException {
+ T result = (T) new Locked() {
+
+ @Override
+ protected Object run(Node node) throws RepositoryException {
+ return exection.execute(node);
+ }
+
+ }.with(node, exection.isDeepLocked());
+ return result;
+ }
+
+
+
+}
Added: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java?rev=951847&view=auto
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java (added)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java Sun Jun 6 10:00:14 2010
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.InvalidItemStateException;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * The NodeLocker takes care of locking a {@link Node} and execute the {@link NodeLockedExecution} on it. The implementations need to take care of prevent a {@link InvalidItemStateException}
+ * in all cases
+ *
+ */
+public interface NodeLocker {
+
+ /**
+ * Execute the given {@link NodeLockedExecution} after locking the {@link Node}
+ * @param <T> the return type of the method
+ * @param exection
+ * @param node
+ * @param returnType
+ * @return result
+ * @throws RepositoryException
+ * @throws InterruptedException
+ */
+ public <T>T execute(NodeLockedExecution<T> exection, Node node, Class<T> returnType) throws RepositoryException, InterruptedException;
+
+ /**
+ * Execute some code on a Node
+ *
+ * @param <T>
+ */
+ public interface NodeLockedExecution<T> {
+
+ /**
+ * Execute some code on the locked {@link Node}
+ * @param node
+ * @return result
+ * @throws RepositoryException
+ */
+ public T execute(Node node) throws RepositoryException;
+
+ /**
+ * Return true if the node needs to be deep locked (all childs too)
+ *
+ * @return deepLocked
+ */
+ public boolean isDeepLocked();
+ }
+}
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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -36,6 +36,7 @@ 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.MailboxSessionJCRRepository;
+import org.apache.james.imap.jcr.NodeLocker;
import org.apache.james.imap.jcr.mail.model.JCRMailbox;
import org.apache.james.imap.mailbox.MailboxNotFoundException;
import org.apache.james.imap.mailbox.MailboxSession;
@@ -52,8 +53,8 @@ public class JCRMailboxMapper extends Ab
private char delimiter;
- public JCRMailboxMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final Log logger, char delimiter) {
- super(repos, session, logger);
+ public JCRMailboxMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final NodeLocker locker, final Log logger, char delimiter) {
+ super(repos, session, locker, logger);
this.delimiter = delimiter;
}
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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -38,6 +38,7 @@ 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.MailboxSessionJCRRepository;
+import org.apache.james.imap.jcr.NodeLocker;
import org.apache.james.imap.jcr.mail.model.JCRMessage;
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.mailbox.MessageRange;
@@ -55,8 +56,8 @@ import org.apache.james.imap.store.mail.
*/
public class JCRMessageMapper extends AbstractJCRMapper implements MessageMapper<String> {
- public JCRMessageMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final Log logger) {
- super(repos, session, logger);
+ public JCRMessageMapper(final MailboxSessionJCRRepository repos, MailboxSession session, NodeLocker locker, final Log logger) {
+ super(repos, session, locker, logger);
}
/*
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=951847&r1=951846&r2=951847&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 Sun Jun 6 10:00:14 2010
@@ -34,6 +34,7 @@ import org.apache.jackrabbit.commons.Jcr
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.jcr.AbstractJCRMapper;
import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
+import org.apache.james.imap.jcr.NodeLocker;
import org.apache.james.imap.jcr.user.model.JCRSubscription;
import org.apache.james.imap.mailbox.MailboxSession;
import org.apache.james.imap.mailbox.SubscriptionException;
@@ -46,8 +47,8 @@ import org.apache.james.imap.store.user.
*/
public class JCRSubscriptionMapper extends AbstractJCRMapper implements SubscriptionMapper {
- public JCRSubscriptionMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final Log log) {
- super(repos,session, log);
+ public JCRSubscriptionMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final NodeLocker locker, final Log log) {
+ super(repos,session, locker, log);
}
/*
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org