james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From e...@apache.org
Subject svn commit: r1617517 [1/2] - in /james/mailbox/trunk: ./ cassandra/ cassandra/src/ cassandra/src/main/ cassandra/src/main/java/ cassandra/src/main/java/org/ cassandra/src/main/java/org/apache/ cassandra/src/main/java/org/apache/james/ cassandra/src/mai...
Date Tue, 12 Aug 2014 16:08:58 GMT
Author: eric
Date: Tue Aug 12 16:08:57 2014
New Revision: 1617517

URL: http://svn.apache.org/r1617517
Log:
Add a Cassandra Mailbox implementation, contributed by Philippe Benoit (MAILBOX-12)

Added:
    james/mailbox/trunk/cassandra/
    james/mailbox/trunk/cassandra/pom.xml
    james/mailbox/trunk/cassandra/src/
    james/mailbox/trunk/cassandra/src/main/
    james/mailbox/trunk/cassandra/src/main/java/
    james/mailbox/trunk/cassandra/src/main/java/org/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/
    james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java
    james/mailbox/trunk/cassandra/src/main/resources/
    james/mailbox/trunk/cassandra/src/main/resources/META-INF/
    james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/
    james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml
    james/mailbox/trunk/cassandra/src/reporting-site/
    james/mailbox/trunk/cassandra/src/reporting-site/site.xml
    james/mailbox/trunk/cassandra/src/test/
    james/mailbox/trunk/cassandra/src/test/java/
    james/mailbox/trunk/cassandra/src/test/java/org/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraClusterSingleton.java
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactoryTest.java
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapperTest.java
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidAndModSeqProviderTest.java
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/
    james/mailbox/trunk/cassandra/src/test/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapperTest.java
    james/mailbox/trunk/cassandra/src/test/resources/
Removed:
    james/mailbox/trunk/.gitignore
Modified:
    james/mailbox/trunk/pom.xml

Added: james/mailbox/trunk/cassandra/pom.xml
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/pom.xml?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/pom.xml (added)
+++ james/mailbox/trunk/cassandra/pom.xml Tue Aug 12 16:08:57 2014
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-james-mailbox</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>0.6-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>apache-james-mailbox-cassandra</artifactId>
+    <description>Apache James Mailbox implementation over Cassandra</description>
+    <name>Apache James :: Mailbox :: Cassandra</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${javax.mail.groupId}</groupId>
+            <artifactId>${javax.mail.artifactId}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+	    <groupId>com.datastax.cassandra</groupId>
+	    <artifactId>cassandra-driver-core</artifactId>
+	    <version>${cassandra-driver-core.version}</version>
+        </dependency>
+        <dependency>
+    	    <groupId>org.cassandraunit</groupId>
+   	    <artifactId>cassandra-unit</artifactId>
+            <version>${cassandra-unit.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>noTest</id>
+            <activation>
+                <os>
+                    <family>windows</family>
+                </os>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>true</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>fully.qualified.MainClass</mainClass>
+                         </manifest>
+                    </archive>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxManager.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,57 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra;
+
+import java.util.UUID;
+
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.Authenticator;
+import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailbox.store.StoreMessageManager;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+
+/**
+ * Cassandra implementation of {@link StoreMailboxManager}
+ */
+public class CassandraMailboxManager extends StoreMailboxManager<UUID> {
+    private MailboxPathLocker locker;
+
+    public CassandraMailboxManager(CassandraMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, final MailboxPathLocker locker) {
+        super(mapperFactory, authenticator, locker, new UnionMailboxACLResolver(), new SimpleGroupMembershipResolver());
+        this.locker = locker;
+    }
+
+    @Override
+    protected Mailbox<UUID> doCreateMailbox(MailboxPath mailboxPath, MailboxSession session) throws MailboxException {
+        return new SimpleMailbox<UUID>(mailboxPath, randomUidValidity());
+    }
+
+    @Override
+    protected StoreMessageManager<UUID> createMessageManager(Mailbox<UUID> mailboxRow, MailboxSession session) throws MailboxException {
+        return new CassandraMessageManager(getMapperFactory(), getMessageSearchIndex(), getEventDispatcher(), this.locker, mailboxRow);
+    }
+
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,74 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra;
+
+import java.util.UUID;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.cassandra.mail.CassandraMailboxMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraMessageMapper;
+import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider;
+import org.apache.james.mailbox.cassandra.user.CassandraSubscriptionMapper;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.ModSeqProvider;
+import org.apache.james.mailbox.store.mail.UidProvider;
+import org.apache.james.mailbox.store.user.SubscriptionMapper;
+
+import com.datastax.driver.core.Session;
+
+/**
+ * Cassandra implementation of {@link MailboxSessionMapperFactory}
+ * 
+ */
+public class CassandraMailboxSessionMapperFactory extends MailboxSessionMapperFactory<UUID> {
+    private Session session;
+    private CassandraUidProvider uidProvider;
+    private ModSeqProvider<UUID> modSeqProvider;
+
+    public CassandraMailboxSessionMapperFactory(CassandraUidProvider uidProvider, ModSeqProvider<UUID> modSeqProvider, CassandraSession session) {
+        this.uidProvider = uidProvider;
+        this.modSeqProvider = modSeqProvider;
+        this.session = session;
+    }
+
+    @Override
+    public CassandraMessageMapper createMessageMapper(MailboxSession mailboxSession) {
+        return new CassandraMessageMapper(session, uidProvider, modSeqProvider);
+    }
+
+    @Override
+    public MailboxMapper<UUID> createMailboxMapper(MailboxSession mailboxSession) {
+        return new CassandraMailboxMapper(session);
+    }
+
+    @Override
+    public SubscriptionMapper createSubscriptionMapper(MailboxSession mailboxSession) {
+        return new CassandraSubscriptionMapper(session);
+    }
+
+    public ModSeqProvider<UUID> getModSeqProvider() {
+        return modSeqProvider;
+    }
+
+    public UidProvider<UUID> getUidProvider() {
+        return uidProvider;
+    }
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,57 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra;
+
+import java.util.UUID;
+
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.StoreMessageManager;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.search.MessageSearchIndex;
+
+/**
+ * Cassandra implementation of {@link StoreMessageManager}
+ * 
+ */
+public class CassandraMessageManager extends StoreMessageManager<UUID> {
+
+    public CassandraMessageManager(MailboxSessionMapperFactory<UUID> mapperFactory, MessageSearchIndex<UUID> index, MailboxEventDispatcher<UUID> dispatcher, MailboxPathLocker locker, Mailbox<UUID> mailbox) throws MailboxException {
+        super(mapperFactory, index, dispatcher, locker, mailbox, new UnionMailboxACLResolver(), new SimpleGroupMembershipResolver());
+
+    }
+
+    /**
+     * Support user flags
+     */
+    @Override
+    protected Flags getPermanentFlags(MailboxSession session) {
+        Flags flags = super.getPermanentFlags(session);
+        flags.add(Flags.Flag.USER);
+        return flags;
+    }
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSession.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,149 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra;
+
+import com.datastax.driver.core.CloseFuture;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.RegularStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.ResultSetFuture;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.Statement;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * A Cassandra session with the default keyspace
+ * 
+ */
+public class CassandraSession implements Session {
+    private final static String DEFAULT_CLUSTER_IP = "localhost";
+    private final static int DEFAULT_CLUSTER_PORT = 9042;
+    private final static String DEFAULT_KEYSPACE_NAME = "apache_james";
+    private final static int DEFAULT_REPLICATION_FACTOR = 1;
+
+    private Session session;
+
+    public CassandraSession(String ip, int port, String keyspace, int replicationFactor) {
+        Cluster cluster = Cluster.builder().addContactPoint(ip).withPort(port).build();
+        if (cluster.getMetadata().getKeyspace(keyspace) == null) {
+            initDatabase(cluster, keyspace, replicationFactor);
+        }
+        session = cluster.connect(keyspace);
+    }
+
+    private void initDatabase(Cluster cluster, String keyspace, int replicationFactor) {
+        session = cluster.connect();
+        session.execute("CREATE KEYSPACE IF NOT EXISTS " + keyspace + " WITH replication " + "= {'class':'SimpleStrategy', 'replication_factor':" + replicationFactor + "};");
+        session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".mailbox (" + "id uuid PRIMARY KEY," + "name text, namespace text," + "uidvalidity bigint," + "user text," + "path text" + ");");
+        session.execute("CREATE INDEX IF NOT EXISTS ON " + keyspace + ".mailbox(path);");
+        session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".messageCounter (" + "mailboxId UUID PRIMARY KEY," + "nextUid bigint," + ");");
+        session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".mailboxCounters (" + "mailboxId UUID PRIMARY KEY," + "count counter," + "unseen counter," + "nextModSeq counter" + ");");
+        session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".message (" + "mailboxId UUID," + "uid bigint," + "internalDate timestamp," + "bodyStartOctet int," + "content blob," + "modSeq bigint," + "mediaType text," + "subType text," + "fullContentOctets int," + "bodyOctets int,"
+                + "textualLineCount bigint," + "bodyContent blob," + "headerContent blob," + "flagAnswered boolean," + "flagDeleted boolean," + "flagDraft boolean," + "flagRecent boolean," + "flagSeen boolean," + "flagFlagged boolean," + "flagUser boolean," + "PRIMARY KEY (mailboxId, uid)" + ");");
+        session.execute("CREATE TABLE IF NOT EXISTS " + keyspace + ".subscription (" + "user text," + "mailbox text," + "PRIMARY KEY (mailbox, user)" + ");");
+        session.close();
+    }
+
+    public CassandraSession() {
+        this(DEFAULT_CLUSTER_IP, DEFAULT_CLUSTER_PORT, DEFAULT_KEYSPACE_NAME, DEFAULT_REPLICATION_FACTOR);
+    }
+
+    @Override
+    public String getLoggedKeyspace() {
+        return session.getLoggedKeyspace();
+    }
+
+    @Override
+    public Session init() {
+        return session.init();
+    }
+
+    @Override
+    public ResultSet execute(String query) {
+        return session.execute(query);
+    }
+
+    @Override
+    public ResultSet execute(String query, Object... values) {
+        return session.execute(query, values);
+    }
+
+    @Override
+    public ResultSet execute(Statement statement) {
+        return session.execute(statement);
+    }
+
+    @Override
+    public ResultSetFuture executeAsync(String query) {
+        return session.executeAsync(query);
+    }
+
+    @Override
+    public ResultSetFuture executeAsync(String query, Object... values) {
+        return session.executeAsync(query, values);
+    }
+
+    @Override
+    public ResultSetFuture executeAsync(Statement statement) {
+        return session.executeAsync(statement);
+    }
+
+    @Override
+    public PreparedStatement prepare(String query) {
+        return session.prepare(query);
+    }
+
+    @Override
+    public PreparedStatement prepare(RegularStatement statement) {
+        return session.prepare(statement);
+    }
+
+    @Override
+    public ListenableFuture<PreparedStatement> prepareAsync(String query) {
+        return session.prepareAsync(query);
+    }
+
+    @Override
+    public ListenableFuture<PreparedStatement> prepareAsync(RegularStatement statement) {
+        return session.prepareAsync(statement);
+    }
+
+    @Override
+    public CloseFuture closeAsync() {
+        return session.closeAsync();
+    }
+
+    @Override
+    public void close() {
+        session.close();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return session.isClosed();
+    }
+
+    @Override
+    public Cluster getCluster() {
+        return session.getCluster();
+    }
+
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManager.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,44 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
+import org.apache.james.mailbox.store.user.model.Subscription;
+import org.apache.james.mailbox.store.user.model.impl.SimpleSubscription;
+
+/**
+ * Cassandra implementation of {@link StoreSubscriptionManager}
+ * 
+ */
+public class CassandraSubscriptionManager extends StoreSubscriptionManager {
+
+    public CassandraSubscriptionManager(CassandraMailboxSessionMapperFactory mapperFactory) {
+        super(mapperFactory);
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.StoreSubscriptionManager#createSubscription(org.apache.james.mailbox.MailboxSession,
+     *      java.lang.String)
+     */
+    protected Subscription createSubscription(MailboxSession session, String mailbox) {
+        return new SimpleSubscription(session.getUser().getUserName(), mailbox);
+    }
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,147 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.FIELDS;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.ID;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.NAME;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.NAMESPACE;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.PATH;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.TABLE_NAME;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.UIDVALIDITY;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxTable.USER;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+/**
+ * Data access management for mailbox.
+ */
+public class CassandraMailboxMapper implements MailboxMapper<UUID> {
+
+    private Session session;
+
+    public CassandraMailboxMapper(Session session) {
+        this.session = session;
+    }
+
+    @Override
+    public void delete(Mailbox<UUID> mailbox) throws MailboxException {
+        session.execute(QueryBuilder.delete().from(TABLE_NAME).where(eq(ID, mailbox.getMailboxId())));
+    }
+
+    @Override
+    public Mailbox<UUID> findMailboxByPath(MailboxPath path) throws MailboxException, MailboxNotFoundException {
+        ResultSet resultSet = session.execute(select(FIELDS).from(TABLE_NAME).where(eq(PATH, path.toString())));
+        if (resultSet.isExhausted()) {
+            throw new MailboxNotFoundException(path);
+        } else {
+            return mailbox(resultSet.one());
+        }
+    }
+
+    private SimpleMailbox<UUID> mailbox(Row row) {
+        SimpleMailbox<UUID> mailbox = new SimpleMailbox<UUID>(new MailboxPath(row.getString(NAMESPACE), row.getString(USER), row.getString(NAME)), row.getLong(UIDVALIDITY));
+        mailbox.setMailboxId(row.getUUID(ID));
+        return mailbox;
+    }
+
+    @Override
+    public List<Mailbox<UUID>> findMailboxWithPathLike(MailboxPath path) throws MailboxException {
+        final String regexWithUser = ".*" + path.getNamespace() + ".*" + path.getUser() + ".*" + path.getName() + ".*";
+        final String regexWithoutUser = ".*" + path.getNamespace() + ".*null.*" + path.getName() + ".*";
+        Builder<Mailbox<UUID>> result = ImmutableList.<Mailbox<UUID>> builder();
+        for (Row row : session.execute(select(FIELDS).from(TABLE_NAME))) {
+            if (row.getString(PATH).matches(regexWithUser) || row.getString(PATH).matches(regexWithoutUser)) {
+                result.add(mailbox(row));
+            }
+        }
+        return result.build();
+    }
+
+    @Override
+    public void save(Mailbox<UUID> mailbox) throws MailboxException {
+        Preconditions.checkArgument(mailbox instanceof SimpleMailbox<?>);
+        SimpleMailbox<UUID> simpleMailbox = (SimpleMailbox<UUID>) mailbox;
+        if (simpleMailbox.getMailboxId() == null) {
+            simpleMailbox.setMailboxId(UUID.randomUUID());
+        }
+        upsertMailbox(simpleMailbox);
+    }
+
+    private void upsertMailbox(SimpleMailbox<UUID> mailbox) {
+        session.execute(insertInto(TABLE_NAME).value(ID, mailbox.getMailboxId()).value(NAME, mailbox.getName()).value(NAMESPACE, mailbox.getNamespace()).value(UIDVALIDITY, mailbox.getUidValidity()).value(USER, mailbox.getUser()).value(PATH, path(mailbox).toString()));
+    }
+
+    private MailboxPath path(Mailbox<?> mailbox) {
+        return new MailboxPath(mailbox.getNamespace(), mailbox.getUser(), mailbox.getName());
+    }
+
+    @Override
+    public void endRequest() {
+        // Do nothing
+    }
+
+    @Override
+    public boolean hasChildren(Mailbox<UUID> mailbox, char delimiter) {
+        final String regexWithUser = ".*" + mailbox.getNamespace() + ".*" + mailbox.getUser() + ".*" + mailbox.getName() + delimiter + ".*";
+        final String regexWithoutUser = ".*" + mailbox.getNamespace() + ".*null.*" + mailbox.getName() + delimiter + ".*";
+        for (Row row : session.execute(select(PATH).from(TABLE_NAME))) {
+            if (row.getString(PATH).matches(regexWithUser) || row.getString(PATH).matches(regexWithoutUser)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<Mailbox<UUID>> list() throws MailboxException {
+        Builder<Mailbox<UUID>> result = ImmutableList.<Mailbox<UUID>> builder();
+        for (Row row : session.execute(select(FIELDS).from(TABLE_NAME))) {
+            result.add(mailbox(row));
+        }
+        return result.build();
+    }
+
+    @Override
+    public <T> T execute(Transaction<T> transaction) throws MailboxException {
+        return transaction.run();
+    }
+
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,369 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.asc;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.decr;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.gt;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.incr;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.lt;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_CONTENT;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_OCTECTS;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.BODY_START_OCTET;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.FIELDS;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.FULL_CONTENT_OCTETS;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.HEADER_CONTENT;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.IMAP_UID;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.INTERNAL_DATE;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MAILBOX_ID;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MEDIA_TYPE;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.MOD_SEQ;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.SUB_TYPE;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.TABLE_NAME;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.TEXTUAL_LINE_COUNT;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.ANSWERED;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.DELETED;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.DRAFT;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.FLAGGED;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.JAVAX_MAIL_FLAG;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.RECENT;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.SEEN;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageTable.Flag.USER;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.mail.Flags;
+import javax.mail.Flags.Flag;
+import javax.mail.util.SharedByteArrayInputStream;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable;
+import org.apache.james.mailbox.cassandra.table.CassandraMessageTable;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.SimpleMessageMetaData;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.ModSeqProvider;
+import org.apache.james.mailbox.store.mail.UidProvider;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMessage;
+
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.Assignment;
+import com.datastax.driver.core.querybuilder.Insert;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.datastax.driver.core.querybuilder.Select.Where;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.ImmutableSortedSet.Builder;
+import com.google.common.io.ByteStreams;
+import com.google.common.primitives.Bytes;
+
+/**
+ * Cassandra implementation of a {@link MessageMapper}.
+ */
+public class CassandraMessageMapper implements MessageMapper<UUID> {
+
+    private Session session;
+    private ModSeqProvider<UUID> modSeqProvider;
+    private MailboxSession mailboxSession;
+    private UidProvider<UUID> uidProvider;
+
+    public CassandraMessageMapper(Session session, CassandraUidProvider uidProvider, ModSeqProvider<UUID> modSeqProvider) {
+        this.session = session;
+        this.uidProvider = uidProvider;
+        this.modSeqProvider = modSeqProvider;
+    }
+
+    public CassandraMessageMapper(Session session, CassandraUidProvider uidProvider, CassandraModSeqProvider modSeqProvider, MailboxSession mailboxSession) {
+        this(session, uidProvider, modSeqProvider);
+        this.mailboxSession = mailboxSession;
+    }
+
+    @Override
+    public long countMessagesInMailbox(Mailbox<UUID> mailbox) throws MailboxException {
+        ResultSet results = session.execute(select(CassandraMailboxCountersTable.COUNT).from(CassandraMailboxCountersTable.TABLE_NAME).where(eq(CassandraMailboxCountersTable.MAILBOX_ID, mailbox.getMailboxId())));
+        return results.isExhausted() ? 0 : results.one().getLong(CassandraMailboxCountersTable.COUNT);
+    }
+
+    @Override
+    public long countUnseenMessagesInMailbox(Mailbox<UUID> mailbox) throws MailboxException {
+        ResultSet results = session.execute(select(CassandraMailboxCountersTable.UNSEEN).from(CassandraMailboxCountersTable.TABLE_NAME).where(eq(CassandraMailboxCountersTable.MAILBOX_ID, mailbox.getMailboxId())));
+        if (!results.isExhausted()) {
+            Row row = results.one();
+            if (row.getColumnDefinitions().contains(CassandraMailboxCountersTable.UNSEEN)) {
+                return row.getLong(CassandraMailboxCountersTable.UNSEEN);
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public void delete(Mailbox<UUID> mailbox, Message<UUID> message) throws MailboxException {
+        session.execute(QueryBuilder.delete().from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId())).and(eq(IMAP_UID, message.getUid())));
+        decrementCount(mailbox);
+        if (!message.isSeen()) {
+            decrementUnseen(mailbox);
+        }
+    }
+
+    private void decrementCount(Mailbox<UUID> mailbox) {
+        updateMailbox(mailbox, decr(CassandraMailboxCountersTable.COUNT));
+    }
+
+    private void incrementCount(Mailbox<UUID> mailbox) {
+        updateMailbox(mailbox, incr(CassandraMailboxCountersTable.COUNT));
+    }
+
+    private void decrementUnseen(Mailbox<UUID> mailbox) {
+        updateMailbox(mailbox, decr(CassandraMailboxCountersTable.UNSEEN));
+    }
+
+    private void incrementUnseen(Mailbox<UUID> mailbox) {
+        updateMailbox(mailbox, incr(CassandraMailboxCountersTable.UNSEEN));
+    }
+
+    private void updateMailbox(Mailbox<UUID> mailbox, Assignment operation) {
+        session.execute(update(CassandraMailboxCountersTable.TABLE_NAME).with(operation).where(eq(CassandraMailboxCountersTable.MAILBOX_ID, mailbox.getMailboxId())));
+    }
+
+    @Override
+    public Iterator<Message<UUID>> findInMailbox(Mailbox<UUID> mailbox, MessageRange set, FetchType ftype, int max) throws MailboxException {
+        Builder<Message<UUID>> result = ImmutableSortedSet.<Message<UUID>> naturalOrder();
+        ResultSet rows = session.execute(buildQuery(mailbox, set));
+        for (Row row : rows) {
+            result.add(message(row));
+        }
+        return result.build().iterator();
+    }
+
+    private byte[] getFullContent(Row row) {
+        byte[] headerContent = new byte[row.getBytes(HEADER_CONTENT).remaining()];
+        byte[] bodyContent = new byte[row.getBytes(BODY_CONTENT).remaining()];
+        row.getBytes(HEADER_CONTENT).get(headerContent);
+        row.getBytes(BODY_CONTENT).get(bodyContent);
+        return Bytes.concat(headerContent, bodyContent);
+    }
+
+    private Flags getFlags(Row row) {
+        Flags flags = new Flags();
+        for (String flag : CassandraMessageTable.Flag.ALL) {
+            if (row.getBool(flag)) {
+                flags.add(JAVAX_MAIL_FLAG.get(flag));
+            }
+        }
+        return flags;
+    }
+
+    private PropertyBuilder getPropertyBuilder(Row row) {
+        PropertyBuilder property = new PropertyBuilder();
+        property.setSubType(row.getString(SUB_TYPE));
+        property.setMediaType(row.getString(MEDIA_TYPE));
+        property.setTextualLineCount(row.getLong(TEXTUAL_LINE_COUNT));
+        return property;
+    }
+
+    private Message<UUID> message(Row row) {
+        SimpleMessage<UUID> message = new SimpleMessage<UUID>(row.getDate(INTERNAL_DATE), row.getInt(FULL_CONTENT_OCTETS), row.getInt(BODY_START_OCTET), new SharedByteArrayInputStream(getFullContent(row)), getFlags(row), getPropertyBuilder(row), row.getUUID(MAILBOX_ID));
+        message.setUid(row.getLong(IMAP_UID));
+        return message;
+    }
+
+    private Where buildQuery(Mailbox<UUID> mailbox, MessageRange set) {
+        final MessageRange.Type type = set.getType();
+        switch (type) {
+        case ALL:
+            return selectAll(mailbox);
+        case FROM:
+            return selectFrom(mailbox, set.getUidFrom());
+        case RANGE:
+            return selectRange(mailbox, set.getUidFrom(), set.getUidTo());
+        case ONE:
+            return selectMessage(mailbox, set.getUidFrom());
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    private Where selectAll(Mailbox<UUID> mailbox) {
+        return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId()));
+    }
+
+    private Where selectFrom(Mailbox<UUID> mailbox, long uid) {
+        return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId())).and(gt(IMAP_UID, uid));
+    }
+
+    private Where selectRange(Mailbox<UUID> mailbox, long from, long to) {
+        return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId())).and(gt(IMAP_UID, from)).and(lt(IMAP_UID, to));
+    }
+
+    private Where selectMessage(Mailbox<UUID> mailbox, long uid) {
+        return select(FIELDS).from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId())).and(eq(IMAP_UID, uid));
+    }
+
+    @Override
+    public List<Long> findRecentMessageUidsInMailbox(Mailbox<UUID> mailbox) throws MailboxException {
+        ImmutableList.Builder<Long> result = ImmutableList.<Long> builder();
+        ResultSet rows = session.execute(selectAll(mailbox).orderBy(asc(IMAP_UID)));
+        for (Row row : rows) {
+            if (row.getBool(RECENT)) {
+                result.add(row.getLong(IMAP_UID));
+            }
+        }
+        return result.build();
+    }
+
+    @Override
+    public Long findFirstUnseenMessageUid(Mailbox<UUID> mailbox) throws MailboxException {
+        ResultSet rows = session.execute(selectAll(mailbox).orderBy(asc(IMAP_UID)));
+        for (Row row : rows) {
+            if (!row.getBool(SEEN)) {
+                return row.getLong(IMAP_UID);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(final Mailbox<UUID> mailbox, MessageRange set) throws MailboxException {
+        ImmutableMap.Builder<Long, MessageMetaData> deletedMessages = ImmutableMap.builder();
+        ResultSet messages = session.execute(buildQuery(mailbox, set));
+        for (Row row : messages) {
+            if (row.getBool(DELETED)) {
+                Message<UUID> message = message(row);
+                delete(mailbox, message);
+                deletedMessages.put(message.getUid(), new SimpleMessageMetaData(message));
+            }
+        }
+        return deletedMessages.build();
+    }
+
+    @Override
+    public MessageMetaData move(Mailbox<UUID> mailbox, Message<UUID> original) throws MailboxException {
+        throw new UnsupportedOperationException("Not implemented - see https://issues.apache.org/jira/browse/IMAP-370");
+    }
+
+    @Override
+    public void endRequest() {
+        // Do nothing
+    }
+
+    @Override
+    public long getHighestModSeq(Mailbox<UUID> mailbox) throws MailboxException {
+        return modSeqProvider.highestModSeq(mailboxSession, mailbox);
+    }
+
+    @Override
+    public <T> T execute(Transaction<T> transaction) throws MailboxException {
+        return transaction.run();
+    }
+
+    @Override
+    public MessageMetaData add(Mailbox<UUID> mailbox, Message<UUID> message) throws MailboxException {
+        message.setUid(uidProvider.nextUid(mailboxSession, mailbox));
+        message.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox));
+        MessageMetaData messageMetaData = save(mailbox, message);
+        if (!message.isSeen()) {
+            incrementUnseen(mailbox);
+        }
+        incrementCount(mailbox);
+        return messageMetaData;
+    }
+
+    private MessageMetaData save(Mailbox<UUID> mailbox, Message<UUID> message) throws MailboxException {
+        try {
+            Insert query = insertInto(TABLE_NAME).value(MAILBOX_ID, mailbox.getMailboxId()).value(IMAP_UID, message.getUid()).value(MOD_SEQ, message.getModSeq()).value(INTERNAL_DATE, message.getInternalDate()).value(MEDIA_TYPE, message.getMediaType())
+                    .value(BODY_START_OCTET, message.getFullContentOctets() - message.getBodyOctets()).value(SUB_TYPE, message.getSubType()).value(FULL_CONTENT_OCTETS, message.getFullContentOctets()).value(BODY_OCTECTS, message.getBodyOctets()).value(ANSWERED, message.isAnswered())
+                    .value(DELETED, message.isDeleted()).value(DRAFT, message.isDraft()).value(FLAGGED, message.isFlagged()).value(RECENT, message.isRecent()).value(SEEN, message.isSeen()).value(USER, message.createFlags().contains(Flag.USER)).value(BODY_CONTENT, bindMarker())
+                    .value(HEADER_CONTENT, bindMarker()).value(TEXTUAL_LINE_COUNT, message.getTextualLineCount());
+            PreparedStatement preparedStatement = session.prepare(query.toString());
+            BoundStatement boundStatement = preparedStatement.bind(toByteBuffer(message.getBodyContent()), toByteBuffer(message.getHeaderContent()));
+            session.execute(boundStatement);
+            return new SimpleMessageMetaData(message);
+        } catch (IOException e) {
+            throw new MailboxException("Error saving mail", e);
+        }
+    }
+
+    private ByteBuffer toByteBuffer(InputStream stream) throws IOException {
+        return ByteBuffer.wrap(ByteStreams.toByteArray(stream));
+    }
+
+    @Override
+    public Iterator<UpdatedFlags> updateFlags(Mailbox<UUID> mailbox, Flags flags, boolean value, boolean replace, MessageRange set) throws MailboxException {
+        ImmutableList.Builder<UpdatedFlags> result = ImmutableList.builder();
+        for (Row row : session.execute(buildQuery(mailbox, set))) {
+            Message<UUID> message = message(row);
+            Flags originFlags = message.createFlags();
+            Flags updatedFlags = buildFlags(message, flags, value, replace);
+            message.setFlags(updatedFlags);
+            message.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox));
+            save(mailbox, message);
+            result.add(new UpdatedFlags(message.getUid(), message.getModSeq(), originFlags, updatedFlags));
+        }
+        return result.build().iterator();
+    }
+
+    private Flags buildFlags(Message<UUID> message, Flags flags, boolean value, boolean replace) {
+        if (replace) {
+            return message.createFlags();
+        } else {
+            Flags updatedFlags = message.createFlags();
+            if (value) {
+                updatedFlags.add(flags);
+            } else {
+                updatedFlags.remove(flags);
+            }
+            return updatedFlags;
+        }
+    }
+
+    @Override
+    public MessageMetaData copy(Mailbox<UUID> mailbox, Message<UUID> original) throws MailboxException {
+        original.setUid(uidProvider.nextUid(mailboxSession, mailbox));
+        original.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox));
+        return save(mailbox, original);
+    }
+
+    @Override
+    public long getLastUid(Mailbox<UUID> mailbox) throws MailboxException {
+        return uidProvider.lastUid(mailboxSession, mailbox);
+    }
+
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java Tue Aug 12 16:08:57 2014
@@ -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.mailbox.cassandra.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.incr;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable.MAILBOX_ID;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable.NEXT_MOD_SEQ;
+import static org.apache.james.mailbox.cassandra.table.CassandraMailboxCountersTable.TABLE_NAME;
+
+import java.util.UUID;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.ModSeqProvider;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
+
+public class CassandraModSeqProvider implements ModSeqProvider<UUID> {
+
+    private Session session;
+
+    public CassandraModSeqProvider(Session session) {
+        this.session = session;
+    }
+
+    @Override
+    public long nextModSeq(MailboxSession mailboxSession, Mailbox<UUID> mailbox) throws MailboxException {
+        session.execute(update(TABLE_NAME).with(incr(NEXT_MOD_SEQ)).where(eq(MAILBOX_ID, mailbox.getMailboxId())));
+        return highestModSeq(mailboxSession, mailbox);
+    }
+
+    @Override
+    public long highestModSeq(MailboxSession mailboxSession, Mailbox<UUID> mailbox) throws MailboxException {
+        ResultSet result = session.execute(select(NEXT_MOD_SEQ).from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId())));
+        return result.isExhausted() ? 0 : result.one().getLong(NEXT_MOD_SEQ);
+    }
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProvider.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,69 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.mail;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.set;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable.MAILBOX_ID;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable.NEXT_UID;
+import static org.apache.james.mailbox.cassandra.table.CassandraMessageUidTable.TABLE_NAME;
+
+import java.util.UUID;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.UidProvider;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
+
+public class CassandraUidProvider implements UidProvider<UUID> {
+    private Session session;
+    private final int applied = 0;
+
+    public CassandraUidProvider(Session session) {
+        this.session = session;
+    }
+
+    @Override
+    public long nextUid(MailboxSession mailboxSession, Mailbox<UUID> mailbox) throws MailboxException {
+        ResultSet resultat = null;
+        long lastUid = lastUid(mailboxSession, mailbox);
+        if (lastUid == 0) {
+            resultat = session.execute(update(TABLE_NAME).with(set(NEXT_UID, ++lastUid)).where(eq(MAILBOX_ID, mailbox.getMailboxId())));
+        } else {
+            do {
+                lastUid = lastUid(mailboxSession, mailbox);
+                resultat = session.execute(update(TABLE_NAME).onlyIf(eq(NEXT_UID, lastUid)).with(set(NEXT_UID, ++lastUid)).where(eq(MAILBOX_ID, mailbox.getMailboxId())));
+            } while (!resultat.one().getBool(applied));
+        }
+        return lastUid;
+    }
+
+    @Override
+    public long lastUid(MailboxSession mailboxSession, Mailbox<UUID> mailbox) throws MailboxException {
+        ResultSet result = session.execute(select(NEXT_UID).from(TABLE_NAME).where(eq(MAILBOX_ID, mailbox.getMailboxId())));
+        return result.isExhausted() ? 0 : result.one().getLong(NEXT_UID);
+    }
+
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxCountersTable.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,28 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.table;
+
+public interface CassandraMailboxCountersTable {
+    String TABLE_NAME = "mailboxCounters";
+    String MAILBOX_ID = "mailboxId";
+    String COUNT = "count";
+    String UNSEEN = "unseen";
+    String NEXT_MOD_SEQ = "nextModSeq";
+}
\ No newline at end of file

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMailboxTable.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,31 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.table;
+
+public interface CassandraMailboxTable {
+    String TABLE_NAME = "mailbox";
+    String ID = "id";
+    String USER = "user";
+    String PATH = "path";
+    String NAMESPACE = "namespace";
+    String UIDVALIDITY = "uidvalidity";
+    String NAME = "name";
+    String[] FIELDS = { ID, USER, NAMESPACE, UIDVALIDITY, NAME, PATH };
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageTable.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,57 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.table;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+
+public interface CassandraMessageTable {
+
+    String TABLE_NAME = "message";
+    String MAILBOX_ID = "mailboxId";
+    String IMAP_UID = "uid";
+    String INTERNAL_DATE = "internalDate";
+    String BODY_START_OCTET = "bodyStartOctet";
+    String CONTENT = "content";
+    String MOD_SEQ = "modSeq";
+    String MEDIA_TYPE = "mediaType";
+    String SUB_TYPE = "subType";
+    String FULL_CONTENT_OCTETS = "fullContentOctets";
+    String BODY_OCTECTS = "bodyOctets";
+    String TEXTUAL_LINE_COUNT = "textualLineCount";
+    String BODY_CONTENT = "bodyContent";
+    String HEADER_CONTENT = "headerContent";
+    String[] FIELDS = { MAILBOX_ID, IMAP_UID, INTERNAL_DATE, MOD_SEQ, BODY_START_OCTET, MEDIA_TYPE, SUB_TYPE, FULL_CONTENT_OCTETS, BODY_OCTECTS, Flag.ANSWERED, Flag.DELETED, Flag.DRAFT, Flag.FLAGGED, Flag.RECENT, Flag.SEEN, Flag.USER, BODY_CONTENT, HEADER_CONTENT, TEXTUAL_LINE_COUNT };
+
+    interface Flag {
+        String ANSWERED = "flagAnswered";
+        String DELETED = "flagDeleted";
+        String DRAFT = "flagDraft";
+        String RECENT = "flagRecent";
+        String SEEN = "flagSeen";
+        String FLAGGED = "flagFlagged";
+        String USER = "flagUser";
+        String[] ALL = { ANSWERED, DELETED, DRAFT, RECENT, SEEN, FLAGGED, USER };
+
+        ImmutableMap<String, javax.mail.Flags.Flag> JAVAX_MAIL_FLAG = new Builder<String, javax.mail.Flags.Flag>().put(ANSWERED, javax.mail.Flags.Flag.ANSWERED).put(DELETED, javax.mail.Flags.Flag.DELETED).put(DRAFT, javax.mail.Flags.Flag.DRAFT).put(RECENT, javax.mail.Flags.Flag.RECENT)
+                .put(SEEN, javax.mail.Flags.Flag.SEEN).put(FLAGGED, javax.mail.Flags.Flag.FLAGGED).put(USER, javax.mail.Flags.Flag.USER).build();
+
+    }
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageUidTable.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,26 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.table;
+
+public interface CassandraMessageUidTable {
+    String TABLE_NAME = "messageCounter";
+    String MAILBOX_ID = "mailboxId";
+    String NEXT_UID = "nextUid";
+}
\ No newline at end of file

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraSubscriptionTable.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,29 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.table;
+
+public interface CassandraSubscriptionTable {
+
+    String TABLE_NAME = "subscription";
+    String USER = "user";
+    String MAILBOX = "mailbox";
+    String[] FIELDS = { MAILBOX, USER };
+
+}

Added: james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java (added)
+++ james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/user/CassandraSubscriptionMapper.java Tue Aug 12 16:08:57 2014
@@ -0,0 +1,95 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.user;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.FIELDS;
+import static org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.MAILBOX;
+import static org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.TABLE_NAME;
+import static org.apache.james.mailbox.cassandra.table.CassandraSubscriptionTable.USER;
+
+import java.util.List;
+
+import org.apache.james.mailbox.store.transaction.NonTransactionalMapper;
+import org.apache.james.mailbox.store.user.SubscriptionMapper;
+import org.apache.james.mailbox.store.user.model.Subscription;
+import org.apache.james.mailbox.store.user.model.impl.SimpleSubscription;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.querybuilder.Insert;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+import com.datastax.driver.core.querybuilder.Select;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+public class CassandraSubscriptionMapper extends NonTransactionalMapper implements SubscriptionMapper {
+    private Session session;
+
+    public CassandraSubscriptionMapper(Session session) {
+        this.session = session;
+    }
+
+    @Override
+    public synchronized void delete(Subscription subscription) {
+        session.execute(QueryBuilder.delete().from(TABLE_NAME).where(eq(USER, subscription.getUser())).and(eq(MAILBOX, subscription.getMailbox())));
+    }
+
+    @Override
+    public Subscription findMailboxSubscriptionForUser(String user, String mailbox) {
+        ResultSet results = session.execute(select(MAILBOX).from(TABLE_NAME).where(eq(USER, user)).and(eq(MAILBOX, mailbox)));
+        return !results.isExhausted() ? new SimpleSubscription(user, mailbox) : null;
+    }
+
+    @Override
+    public List<Subscription> findSubscriptionsForUser(String user) {
+        Builder<Subscription> result = ImmutableList.<Subscription> builder();
+        Select query = select(MAILBOX).from(TABLE_NAME);
+        query.where(eq(USER, user));
+        query.allowFiltering();
+        for (Row row : session.execute(query)) {
+            result.add(new SimpleSubscription(user, row.getString(MAILBOX)));
+        }
+        return result.build();
+    }
+
+    @Override
+    public synchronized void save(Subscription subscription) {
+        Insert query = insertInto(TABLE_NAME).value(USER, subscription.getUser()).value(MAILBOX, subscription.getMailbox());
+        session.execute(query);
+    }
+
+    public List<SimpleSubscription> list() {
+        Builder<SimpleSubscription> result = ImmutableList.<SimpleSubscription> builder();
+        for (Row row : session.execute(select(FIELDS).from(TABLE_NAME))) {
+            result.add(new SimpleSubscription(row.getString(USER), row.getString(MAILBOX)));
+        }
+        return result.build();
+    }
+
+    @Override
+    public void endRequest() {
+        // nothing todo
+    }
+
+}

Added: james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml (added)
+++ james/mailbox/trunk/cassandra/src/main/resources/META-INF/spring/mailbox-cassandra.xml Tue Aug 12 16:08:57 2014
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.    
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+    <!-- 
+      Mailbox Cassandra
+    -->
+    <bean id="cassandra-mailboxmanager" class="org.apache.james.mailbox.cassandra.CassandraMailboxManager" init-method="init">
+        <constructor-arg index="0" ref="cassandra-sessionMapperFactory"/>
+        <constructor-arg index="1" ref="authenticator"/>
+        <constructor-arg index="2" ref="cassandra-locker"/>
+    </bean>
+
+    <bean id ="cassandra-subscriptionManager" class="org.apache.james.mailbox.cassandra.CassandraSubscriptionManager">
+        <constructor-arg index="0" ref="cassandra-sessionMapperFactory"/>
+    </bean>
+
+    <bean id="cassandra-sessionMapperFactory" class="org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory">
+        <constructor-arg index="0" ref="cassandra-uidProvider"/>
+        <constructor-arg index="1" ref="cassandra-modSeqProvider"/>
+        <constructor-arg index="2" ref="cassandra-session"/>
+    </bean>
+
+    <bean id="cassandra-uidProvider" class="org.apache.james.mailbox.cassandra.mail.CassandraUidProvider">
+        <constructor-arg index="0" ref="cassandra-session"/>
+    </bean>
+
+    <bean id="cassandra-modSeqProvider" class="org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider">
+        <constructor-arg index="0" ref="cassandra-session"/>
+    </bean>
+
+    <!--
+      The parameters are : the IP of a Cassendra cluster, the port, the keyspace and the replication factor
+      Default values are : localhost, 9042, apache_james and 1
+    -->
+    <bean id="cassandra-session" class="org.apache.james.mailbox.cassandra.CassandraSession">
+        <constructor-arg index="0" value="localhost"/>
+        <constructor-arg index="1" value="9042" type="int"/>
+        <constructor-arg index="2" value="apache_james"/>
+        <constructor-arg index="3" value="1" type="int"/>
+    </bean>
+
+    <alias name="jvm-locker" alias="cassandra-locker"/>
+
+</beans>

Added: james/mailbox/trunk/cassandra/src/reporting-site/site.xml
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/reporting-site/site.xml?rev=1617517&view=auto
==============================================================================
--- james/mailbox/trunk/cassandra/src/reporting-site/site.xml (added)
+++ james/mailbox/trunk/cassandra/src/reporting-site/site.xml Tue Aug 12 16:08:57 2014
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.    
+-->
+<project name="${project.name}">
+
+    <body>
+
+        <menu ref="parent" />
+        <menu ref="reports" />
+
+    </body>
+
+</project>



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message