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 bt...@apache.org on 2015/10/24 17:27:12 UTC

svn commit: r1710357 - in /james/project/trunk/server: container/filesystem-api/ container/filesystem-api/src/main/java/org/apache/james/filesystem/api/ container/filesystem-api/src/test/java/org/apache/james/filesystem/api/ container/spring/src/main/r...

Author: btellier
Date: Sat Oct 24 15:27:11 2015
New Revision: 1710357

URL: http://svn.apache.org/viewvc?rev=1710357&view=rev
Log:
JAMES-1614 Move SieveRepository to data folder - contributed by Erwan Guyomarc'h and me

Added:
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/ScriptSummary.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateUserException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/IsActiveException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaExceededException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaNotFoundException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/ScriptNotFoundException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/SieveRepositoryException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/StorageException.java
    james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/UserNotFoundException.java
    james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/
    james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/
    james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java
    james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/
    james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/
    james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTestCase.java
Removed:
    james/project/trunk/server/container/filesystem-api/src/main/java/org/apache/james/filesystem/api/SieveFileRepository.java
    james/project/trunk/server/container/filesystem-api/src/test/java/org/apache/james/filesystem/api/SieveFileRepositoryTestCase.java
Modified:
    james/project/trunk/server/container/filesystem-api/pom.xml
    james/project/trunk/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml

Modified: james/project/trunk/server/container/filesystem-api/pom.xml
URL: http://svn.apache.org/viewvc/james/project/trunk/server/container/filesystem-api/pom.xml?rev=1710357&r1=1710356&r2=1710357&view=diff
==============================================================================
--- james/project/trunk/server/container/filesystem-api/pom.xml (original)
+++ james/project/trunk/server/container/filesystem-api/pom.xml Sat Oct 24 15:27:11 2015
@@ -35,10 +35,6 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.james</groupId>
-            <artifactId>apache-jsieve-manager-api</artifactId>
-        </dependency>
-        <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
         </dependency>

Modified: james/project/trunk/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml
URL: http://svn.apache.org/viewvc/james/project/trunk/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml?rev=1710357&r1=1710356&r2=1710357&view=diff
==============================================================================
--- james/project/trunk/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml (original)
+++ james/project/trunk/server/container/spring/src/main/resources/META-INF/spring/loaders-context.xml Sat Oct 24 15:27:11 2015
@@ -123,7 +123,7 @@
     <!--<bean id="filesystem" class="org.apache.james.container.spring.filesystem.FileSystemImpl" autowire="byName"/>-->
     <bean id="filesystem" class="org.apache.james.container.spring.filesystem.ResourceLoaderFileSystem"/>
 
-    <bean id="sieverepository" class="org.apache.james.filesystem.api.SieveFileRepository">
+    <bean id="sieverepository" class="org.apache.james.sieverepository.file.SieveFileRepository">
         <constructor-arg index="0" ref="filesystem"/>
     </bean>
 

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/ScriptSummary.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/ScriptSummary.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/ScriptSummary.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/ScriptSummary.java Sat Oct 24 15:27:11 2015
@@ -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.sieverepository.api;
+
+public class ScriptSummary {
+
+    private final String name;
+    private final boolean activeFile;
+
+    public ScriptSummary(String name, boolean activeFile) {
+        this.name = name;
+        this.activeFile = activeFile;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean isActive() {
+        return activeFile;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ScriptSummary)) return false;
+
+        ScriptSummary that = (ScriptSummary) o;
+
+        if (activeFile != that.activeFile) return false;
+        return !(name != null ? !name.equals(that.name) : that.name != null);
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (activeFile ? 1 : 0);
+        return result;
+    }
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/SieveRepository.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,91 @@
+/*
+ *   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.sieverepository.api;
+
+import org.apache.james.sieverepository.api.exception.DuplicateException;
+import org.apache.james.sieverepository.api.exception.DuplicateUserException;
+import org.apache.james.sieverepository.api.exception.IsActiveException;
+import org.apache.james.sieverepository.api.exception.QuotaExceededException;
+import org.apache.james.sieverepository.api.exception.QuotaNotFoundException;
+import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
+import org.apache.james.sieverepository.api.exception.StorageException;
+import org.apache.james.sieverepository.api.exception.UserNotFoundException;
+
+import java.util.List;
+
+
+
+/**
+ * <code>SieveRepository</code>
+ */
+public interface SieveRepository {
+    
+    void haveSpace(String user, String name, long size) throws UserNotFoundException, QuotaExceededException, StorageException;
+    
+    /**
+     * PutScript.
+     *
+     * <p><strong>Note:</strong> It is the responsibility of the caller to validate the script to be put.
+     *
+     * @param user
+     * @param name
+     * @param content
+     * @throws UserNotFoundException
+     * @throws StorageException
+     * @throws QuotaExceededException
+     */
+    void putScript(String user, String name, String content) throws UserNotFoundException, StorageException, QuotaExceededException;
+    
+    List<ScriptSummary> listScripts(String user) throws UserNotFoundException, StorageException;
+    
+    String getActive(String user) throws UserNotFoundException, ScriptNotFoundException, StorageException;
+    
+    void setActive(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException;
+    
+    String getScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, StorageException;
+    
+    void deleteScript(String user, String name) throws UserNotFoundException, ScriptNotFoundException, IsActiveException, StorageException;
+    
+    void renameScript(String user, String oldName, String newName) throws UserNotFoundException, ScriptNotFoundException, DuplicateException, StorageException;
+    
+    boolean hasUser(String user) throws StorageException;
+    
+    void addUser(String user) throws DuplicateUserException, StorageException;
+    
+    void removeUser(String user) throws UserNotFoundException, StorageException;
+
+    boolean hasQuota() throws StorageException;
+    
+    long getQuota() throws QuotaNotFoundException, StorageException;
+    
+    void setQuota(long quota) throws StorageException;
+    
+    void removeQuota() throws QuotaNotFoundException, StorageException;
+    
+    boolean hasQuota(String user) throws UserNotFoundException, StorageException;
+    
+    long getQuota(String user) throws UserNotFoundException, QuotaNotFoundException, StorageException;
+    
+    void setQuota(String user, long quota) throws UserNotFoundException, StorageException;
+    
+    void removeQuota(String user) throws UserNotFoundException, QuotaNotFoundException, StorageException;
+
+}

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,61 @@
+/*
+ *   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.sieverepository.api.exception;
+
+public class DuplicateException extends SieveRepositoryException {
+    /**
+     * Creates a new instance of DuplicateException.
+     *
+     */
+    public DuplicateException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of DuplicateException.
+     *
+     * @param message
+     * @param cause
+     */
+    public DuplicateException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of DuplicateException.
+     *
+     * @param message
+     */
+    public DuplicateException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of DuplicateException.
+     *
+     * @param cause
+     */
+    public DuplicateException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = 7384835765215418347L;
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateUserException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateUserException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateUserException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/DuplicateUserException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,65 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.james.sieverepository.api.exception;
+
+/**
+ * <code>DuplicateUserException</code>
+ */
+public class DuplicateUserException extends SieveRepositoryException {
+
+    private static final long serialVersionUID = 2393178076895724704L;
+
+    /**
+     * Creates a new instance of DuplicateUserException.
+     *
+     */
+    public DuplicateUserException() {
+    }
+
+    /**
+     * Creates a new instance of DuplicateUserException.
+     *
+     * @param message
+     * @param cause
+     */
+    public DuplicateUserException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of DuplicateUserException.
+     *
+     * @param message
+     */
+    public DuplicateUserException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of DuplicateUserException.
+     *
+     * @param cause
+     */
+    public DuplicateUserException(Throwable cause) {
+        super(cause);
+    }
+
+}

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/IsActiveException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/IsActiveException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/IsActiveException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/IsActiveException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,61 @@
+/*
+ *   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.sieverepository.api.exception;
+
+public class IsActiveException extends SieveRepositoryException {
+    /**
+     * Creates a new instance of IsActiveException.
+     *
+     */
+    public IsActiveException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of IsActiveException.
+     *
+     * @param message
+     * @param cause
+     */
+    public IsActiveException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of IsActiveException.
+     *
+     * @param message
+     */
+    public IsActiveException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of IsActiveException.
+     *
+     * @param cause
+     */
+    public IsActiveException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = 7472385325048232256L;
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaExceededException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaExceededException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaExceededException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaExceededException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,62 @@
+/*
+ *   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.sieverepository.api.exception;
+
+public class QuotaExceededException extends SieveRepositoryException
+{
+    /**
+     * Creates a new instance of QuotaExceededException.
+     *
+     */
+    public QuotaExceededException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of QuotaExceededException.
+     *
+     * @param message
+     * @param cause
+     */
+    public QuotaExceededException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of QuotaExceededException.
+     *
+     * @param message
+     */
+    public QuotaExceededException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of QuotaExceededException.
+     *
+     * @param cause
+     */
+    public QuotaExceededException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = -3966867419152420878L;
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaNotFoundException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaNotFoundException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaNotFoundException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/QuotaNotFoundException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,64 @@
+/*
+ *   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.sieverepository.api.exception;
+
+/**
+ * <code>QuotaNotFoundException</code>
+ */
+public class QuotaNotFoundException extends SieveRepositoryException {
+    private static final long serialVersionUID = 6523546952593451503L;
+
+    /**
+     * Creates a new instance of QuotaNotFoundException.
+     *
+     */
+    public QuotaNotFoundException() {
+    }
+
+    /**
+     * Creates a new instance of QuotaNotFoundException.
+     *
+     * @param message
+     * @param cause
+     */
+    public QuotaNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of QuotaNotFoundException.
+     *
+     * @param message
+     */
+    public QuotaNotFoundException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of QuotaNotFoundException.
+     *
+     * @param cause
+     */
+    public QuotaNotFoundException(Throwable cause) {
+        super(cause);
+    }
+
+}

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/ScriptNotFoundException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/ScriptNotFoundException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/ScriptNotFoundException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/ScriptNotFoundException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,61 @@
+/*
+ *   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.sieverepository.api.exception;
+
+public class ScriptNotFoundException extends SieveRepositoryException {
+    /**
+     * Creates a new instance of ScriptNotFoundException.
+     *
+     */
+    public ScriptNotFoundException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of ScriptNotFoundException.
+     *
+     * @param message
+     * @param cause
+     */
+    public ScriptNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of ScriptNotFoundException.
+     *
+     * @param message
+     */
+    public ScriptNotFoundException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of ScriptNotFoundException.
+     *
+     * @param cause
+     */
+    public ScriptNotFoundException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = 4200071956828484819L;
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/SieveRepositoryException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/SieveRepositoryException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/SieveRepositoryException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/SieveRepositoryException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,61 @@
+/*
+ *   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.sieverepository.api.exception;
+
+public class SieveRepositoryException extends Exception {
+    /**
+     * Creates a new instance of SieveRepositoryException.
+     *
+     */
+    public SieveRepositoryException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of SieveRepositoryException.
+     *
+     * @param message
+     * @param cause
+     */
+    public SieveRepositoryException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of SieveRepositoryException.
+     *
+     * @param message
+     */
+    public SieveRepositoryException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of SieveRepositoryException.
+     *
+     * @param cause
+     */
+    public SieveRepositoryException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = -1446993382609775076L;        
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/StorageException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/StorageException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/StorageException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/StorageException.java Sat Oct 24 15:27:11 2015
@@ -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.sieverepository.api.exception;
+
+/**
+ * <code>StorageException</code>
+ */
+public class StorageException extends SieveRepositoryException {
+
+    private static final long serialVersionUID = 7374111339714642386L;
+
+    /**
+     * Creates a new instance of StorageException.
+     *
+     */
+    public StorageException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of StorageException.
+     *
+     * @param message
+     * @param cause
+     */
+    public StorageException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of StorageException.
+     *
+     * @param message
+     */
+    public StorageException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of StorageException.
+     *
+     * @param cause
+     */
+    public StorageException(Throwable cause) {
+        super(cause);
+    }
+
+}

Added: james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/UserNotFoundException.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/UserNotFoundException.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/UserNotFoundException.java (added)
+++ james/project/trunk/server/data/data-api/src/main/java/org/apache/james/sieverepository/api/exception/UserNotFoundException.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,61 @@
+/*
+ *   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.sieverepository.api.exception;
+
+public class UserNotFoundException extends SieveRepositoryException {
+    /**
+     * Creates a new instance of UserNotFoundException.
+     *
+     */
+    public UserNotFoundException() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of UserNotFoundException.
+     *
+     * @param message
+     * @param cause
+     */
+    public UserNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new instance of UserNotFoundException.
+     *
+     * @param message
+     */
+    public UserNotFoundException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new instance of UserNotFoundException.
+     *
+     * @param cause
+     */
+    public UserNotFoundException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = -5075227645788455698L;
+}
\ No newline at end of file

Added: james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java (added)
+++ james/project/trunk/server/data/data-file/src/main/java/org/apache/james/sieverepository/file/SieveFileRepository.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,552 @@
+/*
+ *   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.sieverepository.file;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.sieverepository.api.exception.DuplicateException;
+import org.apache.james.sieverepository.api.exception.DuplicateUserException;
+import org.apache.james.sieverepository.api.exception.IsActiveException;
+import org.apache.james.sieverepository.api.exception.QuotaExceededException;
+import org.apache.james.sieverepository.api.exception.QuotaNotFoundException;
+import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
+import org.apache.james.sieverepository.api.ScriptSummary;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.sieverepository.api.exception.StorageException;
+import org.apache.james.sieverepository.api.exception.UserNotFoundException;
+
+import javax.inject.Inject;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Scanner;
+
+/**
+ * <code>SieveFileRepository</code> manages sieve scripts stored on the file system.
+ * <p>The sieve root directory is a sub-directory of the application base directory named "sieve".
+ * Scripts are stored in sub-directories of the sieve root directory, each with the name of the
+ * associated user.
+ */
+public class SieveFileRepository implements SieveRepository {
+
+    private static final String SIEVE_ROOT = FileSystem.FILE_PROTOCOL + "sieve/";
+    private static final String UTF_8 = "UTF-8";
+    private static final String FILE_NAME_QUOTA = ".quota";
+    private static final String FILE_NAME_ACTIVE = ".active";
+    private static final List<String> SYSTEM_FILES = Arrays.asList(FILE_NAME_QUOTA, FILE_NAME_ACTIVE);
+    private static final int MAX_BUFF_SIZE = 32768;
+    public static final String SIEVE_EXTENSION = ".sieve";
+
+    private FileSystem _fileSystem = null;
+    private final Object lock = new Object();
+
+    /**
+     * Read a file with the specified encoding into a String
+     *
+     * @param file
+     * @param encoding
+     * @return
+     * @throws FileNotFoundException
+     */
+    static protected String toString(File file, String encoding) throws FileNotFoundException {
+        String script = null;
+        Scanner scanner = null;
+        try {
+            scanner = new Scanner(file, encoding).useDelimiter("\\A");
+            script = scanner.next();
+        } finally {
+            if (null != scanner) {
+                scanner.close();
+            }
+        }
+        return script;
+    }
+
+    static protected void toFile(File file, String content) throws StorageException {
+        // Create a temporary file
+        int bufferSize = content.length() > MAX_BUFF_SIZE ? MAX_BUFF_SIZE : content.length();
+        File tmpFile = null;
+        Writer out = null;
+        try {
+            tmpFile = File.createTempFile(file.getName(), ".tmp", file.getParentFile());
+            out = new OutputStreamWriter(new BufferedOutputStream(
+                    new FileOutputStream(tmpFile), bufferSize), UTF_8);
+            out.write(content);
+        } catch (IOException ex) {
+            FileUtils.deleteQuietly(tmpFile);
+            throw new StorageException(ex);
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
+
+        // Does the file exist?
+        // If so, make a backup
+        File backupFile = new File(file.getParentFile(), file.getName() + ".bak");
+        if (file.exists()) {
+            try {
+                FileUtils.copyFile(file, backupFile);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+
+        // Copy the temporary file to its final name
+        try {
+            FileUtils.copyFile(tmpFile, file);
+        } catch (IOException ex) {
+            throw new StorageException(ex);
+        }
+        // Tidy up
+        if (tmpFile.exists()) {
+            FileUtils.deleteQuietly(tmpFile);
+        }
+        if (backupFile.exists()) {
+            FileUtils.deleteQuietly(backupFile);
+        }
+    }
+
+    /**
+     * Creates a new instance of SieveFileRepository.
+     */
+    public SieveFileRepository() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of SieveFileRepository.
+     *
+     * @param fileSystem
+     */
+    public SieveFileRepository(FileSystem fileSystem) {
+        this();
+        setFileSystem(fileSystem);
+    }
+
+    @Inject
+    public void setFileSystem(FileSystem fileSystem) {
+        _fileSystem = fileSystem;
+    }
+
+    @Override
+    public void deleteScript(final String user, final String name) throws UserNotFoundException,
+            ScriptNotFoundException, IsActiveException, StorageException {
+        synchronized (lock) {
+            File file = getScriptFile(user, name);
+            if (isActiveFile(user, file)) {
+                throw new IsActiveException("User: " + user + "Script: " + name);
+            }
+            try {
+                FileUtils.forceDelete(file);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+    }
+
+    @Override
+    public String getScript(final String user, final String name) throws UserNotFoundException,
+            ScriptNotFoundException, StorageException {
+        String script;
+        try {
+            script = toString(getScriptFile(user, name), UTF_8);
+        } catch (FileNotFoundException ex) {
+            throw new ScriptNotFoundException(ex);
+        }
+        return script;
+    }
+
+    /**
+     * The default quota, if any, is stored in file '.quota' in the sieve root directory. Quotas for
+     * specific users are stored in file '.quota' in the user's directory.
+     * <p/>
+     * <p>The '.quota' file contains a single positive integer value representing the quota in octets.
+     *
+     * @see SieveRepository#haveSpace(java.lang.String, java.lang.String, long)
+     */
+    @Override
+    public void haveSpace(final String user, final String name, final long size) throws UserNotFoundException,
+            QuotaExceededException, StorageException {
+        long usedSpace = 0;
+        for (File file : getUserDirectory(user).listFiles()) {
+            if (!(file.getName().equals(name) || SYSTEM_FILES.contains(file.getName()))) {
+                usedSpace = usedSpace + file.length();
+            }
+        }
+
+        long quota = Long.MAX_VALUE;
+        File file = getQuotaFile(user);
+        if (!file.exists()) {
+            file = getQuotaFile();
+        }
+        if (file.exists()) {
+            Scanner scanner = null;
+            try {
+                scanner = new Scanner(file, UTF_8);
+                quota = scanner.nextLong();
+            } catch (FileNotFoundException ex) {
+                // no op
+            } catch (NoSuchElementException ex) {
+                // no op
+            } finally {
+                if (null != scanner) {
+                    scanner.close();
+                }
+            }
+        }
+        if ((usedSpace + size) > quota) {
+            throw new QuotaExceededException(" Quota: " + quota + " Used: " + usedSpace
+                    + " Requested: " + size);
+        }
+    }
+
+    @Override
+    public List<ScriptSummary> listScripts(final String user) throws UserNotFoundException, StorageException {
+        File[] files = getUserDirectory(user).listFiles();
+        List<ScriptSummary> summaries = new ArrayList<ScriptSummary>(files.length);
+        File activeFile = null;
+        try {
+            activeFile = getActiveFile(user);
+        } catch (ScriptNotFoundException ex) {
+            // no op
+        }
+        for (final File file : files) {
+            if (!SYSTEM_FILES.contains(file.getName())) {
+                summaries.add(new ScriptSummary(file.getName(), isActive(file, activeFile)));
+            }
+        }
+        return summaries;
+    }
+
+    private boolean isActive(File file, File activeFile) {
+        return null != activeFile
+            && activeFile.equals(file);
+    }
+
+    @Override
+    public void putScript(final String user, final String name, final String content)
+            throws UserNotFoundException, StorageException, QuotaExceededException {
+        synchronized (lock) {
+            File file = new File(getUserDirectory(user), name);
+            haveSpace(user, name, content.length());
+            toFile(file, content);
+        }
+    }
+
+    @Override
+    public void renameScript(final String user, final String oldName, final String newName)
+            throws UserNotFoundException, ScriptNotFoundException,
+            DuplicateException, StorageException {
+        synchronized (lock) {
+            File oldFile = getScriptFile(user, oldName);
+            File newFile = new File(getUserDirectory(user), newName);
+            if (newFile.exists()) {
+                throw new DuplicateException("User: " + user + "Script: " + newName);
+            }
+            try {
+                FileUtils.copyFile(oldFile, newFile);
+                if (isActiveFile(user, oldFile)) {
+                    setActiveFile(newFile, user, true);
+                }
+                FileUtils.forceDelete(oldFile);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+    }
+
+    @Override
+    public String getActive(final String user) throws UserNotFoundException,
+            ScriptNotFoundException, StorageException {
+        String script;
+        try {
+            script = toString(getActiveFile(user), UTF_8);
+        } catch (FileNotFoundException ex) {
+            throw new ScriptNotFoundException(ex);
+        }
+        return script;
+    }
+
+    @Override
+    public void setActive(final String user, final String name) throws UserNotFoundException,
+            ScriptNotFoundException, StorageException {
+        synchronized (lock) {
+            // Turn off currently active script, if any
+            File oldActive = null;
+            try {
+                oldActive = getActiveFile(user);
+                setActiveFile(oldActive, user, false);
+            } catch (ScriptNotFoundException ex) {
+                // This is permissible
+            }
+            // Turn on the new active script if not an empty name
+            if ((null != name) && (!name.trim().isEmpty())) {
+                try {
+                    setActiveFile(getScriptFile(user, name), user, true);
+                } catch (ScriptNotFoundException ex) {
+                    if (null != oldActive) {
+                        setActiveFile(oldActive, user, true);
+                    }
+                    throw ex;
+                }
+            }
+        }
+    }
+
+    protected File getSieveRootDirectory() throws StorageException {
+        try {
+            return _fileSystem.getFile(SIEVE_ROOT);
+        } catch (FileNotFoundException ex1) {
+            throw new StorageException(ex1);
+        }
+    }
+
+    protected File getUserDirectory(String user) throws UserNotFoundException, StorageException {
+        File file = getUserDirectoryFile(user);
+        if (!file.exists()) {
+            throw new UserNotFoundException("User: " + user);
+        }
+        return file;
+    }
+
+    protected File getUserDirectoryFile(String user) throws StorageException {
+        return new File(getSieveRootDirectory(), user + '/');
+    }
+
+    protected File getActiveFile(String user) throws UserNotFoundException,
+            ScriptNotFoundException, StorageException {
+        File dir = getUserDirectory(user);
+        String content;
+        try {
+            content = toString(new File(dir, FILE_NAME_ACTIVE), UTF_8);
+        } catch (FileNotFoundException ex) {
+            throw new ScriptNotFoundException("There is no active script.");
+        }
+        return new File(dir, content);
+    }
+
+    protected boolean isActiveFile(String user, File file) throws UserNotFoundException, StorageException {
+        try {
+            return 0 == getActiveFile(user).compareTo(file);
+        } catch (ScriptNotFoundException ex) {
+            return false;
+        }
+    }
+
+    protected void setActiveFile(File scriptToBeActivated, String userName, boolean isActive) throws StorageException {
+        File personalScriptDirectory = scriptToBeActivated.getParentFile();
+        File sieveBaseDirectory = personalScriptDirectory.getParentFile();
+        File activeScriptPersistenceFile = new File(personalScriptDirectory, FILE_NAME_ACTIVE);
+        File activeScriptCopy = new File(sieveBaseDirectory, userName + SIEVE_EXTENSION);
+        if (isActive) {
+            toFile(activeScriptPersistenceFile, scriptToBeActivated.getName());
+            try {
+                FileUtils.copyFile(scriptToBeActivated, activeScriptCopy);
+            } catch (IOException exception) {
+                throw new StorageException("Can not copy active script to make it accessible for sieve utils", exception);
+            }
+        } else {
+            try {
+                FileUtils.forceDelete(activeScriptPersistenceFile);
+                FileUtils.forceDelete(activeScriptCopy);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+    }
+
+    protected File getScriptFile(String user, String name) throws UserNotFoundException,
+            ScriptNotFoundException, StorageException {
+        File file = new File(getUserDirectory(user), name);
+        if (!file.exists()) {
+            throw new ScriptNotFoundException("User: " + user + "Script: " + name);
+        }
+        return file;
+    }
+
+
+    @Override
+    public boolean hasUser(final String user) throws StorageException {
+        boolean userExists = true;
+        try {
+            getUserDirectory(user);
+        } catch (UserNotFoundException ex) {
+            userExists = false;
+        }
+        return userExists;
+    }
+
+    @Override
+    public void addUser(final String user) throws DuplicateUserException, StorageException {
+        synchronized (lock) {
+            boolean userExists = true;
+            try {
+                getUserDirectory(user);
+            } catch (UserNotFoundException ex) {
+                userExists = false;
+            }
+            if (userExists) {
+                throw new DuplicateUserException("User: " + user);
+            }
+            File dir = getUserDirectoryFile(user);
+            try {
+                FileUtils.forceMkdir(dir);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+    }
+
+    @Override
+    public void removeUser(final String user) throws UserNotFoundException, StorageException {
+        synchronized (lock) {
+            File dir = getUserDirectory(user);
+            try {
+                FileUtils.forceDelete(dir);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+    }
+
+    protected File getQuotaFile() throws StorageException {
+        return new File(getSieveRootDirectory(), FILE_NAME_QUOTA);
+    }
+
+    @Override
+    public boolean hasQuota() throws StorageException {
+        return getQuotaFile().exists();
+    }
+
+    @Override
+    public long getQuota() throws QuotaNotFoundException, StorageException {
+        Long quota = null;
+        File file = getQuotaFile();
+        if (file.exists()) {
+            Scanner scanner = null;
+            try {
+                scanner = new Scanner(file, UTF_8);
+                quota = scanner.nextLong();
+            } catch (FileNotFoundException ex) {
+                // no op
+            } catch (NoSuchElementException ex) {
+                // no op
+            } finally {
+                if (null != scanner) {
+                    scanner.close();
+                }
+            }
+        }
+        if (null == quota) {
+            throw new QuotaNotFoundException("No default quota");
+        }
+        return quota;
+    }
+
+    @Override
+    public synchronized void removeQuota() throws QuotaNotFoundException, StorageException {
+        File file = getQuotaFile();
+        if (!file.exists()) {
+            throw new QuotaNotFoundException("No default quota");
+        }
+        try {
+            FileUtils.forceDelete(file);
+        } catch (IOException ex) {
+            throw new StorageException(ex);
+        }
+    }
+
+    @Override
+    public synchronized void setQuota(final long quota) throws StorageException {
+        File file = getQuotaFile();
+        String content = Long.toString(quota);
+        toFile(file, content);
+    }
+
+    protected File getQuotaFile(String user) throws UserNotFoundException, StorageException {
+        return new File(getUserDirectory(user), FILE_NAME_QUOTA);
+    }
+
+    @Override
+    public boolean hasQuota(final String user) throws UserNotFoundException, StorageException {
+        return getQuotaFile(user).exists();
+    }
+
+    @Override
+    public long getQuota(final String user) throws UserNotFoundException, QuotaNotFoundException, StorageException {
+        Long quota = null;
+        File file = getQuotaFile(user);
+        if (file.exists()) {
+            Scanner scanner = null;
+            try {
+                scanner = new Scanner(file, UTF_8);
+                quota = scanner.nextLong();
+            } catch (FileNotFoundException ex) {
+                // no op
+            } catch (NoSuchElementException ex) {
+                // no op
+            } finally {
+                if (null != scanner) {
+                    scanner.close();
+                }
+            }
+        }
+        if (null == quota) {
+            throw new QuotaNotFoundException("No quota for user: " + user);
+        }
+        return quota;
+    }
+
+    @Override
+    public void removeQuota(final String user) throws UserNotFoundException,
+            QuotaNotFoundException, StorageException {
+        synchronized (lock) {
+            File file = getQuotaFile(user);
+            if (!file.exists()) {
+                throw new QuotaNotFoundException("No quota for user: " + user);
+            }
+            try {
+                FileUtils.forceDelete(file);
+            } catch (IOException ex) {
+                throw new StorageException(ex);
+            }
+        }
+    }
+
+    @Override
+    public void setQuota(final String user, final long quota) throws UserNotFoundException,
+            StorageException {
+        synchronized (lock) {
+            File file = getQuotaFile(user);
+            String content = Long.toString(quota);
+            toFile(file, content);
+        }
+    }
+
+}

Added: james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTestCase.java
URL: http://svn.apache.org/viewvc/james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTestCase.java?rev=1710357&view=auto
==============================================================================
--- james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTestCase.java (added)
+++ james/project/trunk/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTestCase.java Sat Oct 24 15:27:11 2015
@@ -0,0 +1,633 @@
+/*
+ *   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.sieverepository.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.sieverepository.api.exception.DuplicateException;
+import org.apache.james.sieverepository.api.exception.DuplicateUserException;
+import org.apache.james.sieverepository.api.exception.IsActiveException;
+import org.apache.james.sieverepository.api.exception.QuotaExceededException;
+import org.apache.james.sieverepository.api.exception.QuotaNotFoundException;
+import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
+import org.apache.james.sieverepository.api.ScriptSummary;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.sieverepository.api.exception.StorageException;
+import org.apache.james.sieverepository.api.exception.UserNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * <code>SieveFileRepositoryTestCase</code>
+ */
+public class SieveFileRepositoryTestCase {
+
+    private static final String SIEVE_ROOT = FileSystem.FILE_PROTOCOL + "sieve";
+    private final FileSystem fs = new FileSystem() {
+
+        @Override
+        public File getBasedir() throws FileNotFoundException {
+            return new File(System.getProperty("java.io.tmpdir"));
+        }
+
+        @Override
+        public InputStream getResource(String url) throws IOException {
+            return new FileInputStream(getFile(url));
+        }
+
+        @Override
+        public File getFile(String fileURL) throws FileNotFoundException {
+            return new File(getBasedir(), fileURL.substring(FileSystem.FILE_PROTOCOL.length()));
+        }
+    };
+
+    /**
+     * setUp.
+     *
+     * @throws java.lang.Exception
+     */
+    @Before
+    public void setUp() throws Exception {
+        File root = fs.getFile(SIEVE_ROOT);
+        // Remove files from the previous test, if any
+        if (root.exists()) {
+            FileUtils.forceDelete(root);
+        }
+        FileUtils.forceMkdir(root);
+    }
+
+    /**
+     * Test method for .
+     */
+    @Test
+    public final void testSieveFileRepository() {
+        SieveRepository repo = new SieveFileRepository(fs);
+        assertTrue(repo instanceof SieveRepository);
+        assertTrue(repo instanceof SieveFileRepository);
+    }
+
+    /**
+     * Test method for .
+     * @throws StorageException 
+     * @throws DuplicateUserException 
+     * @throws QuotaExceededException 
+     * @throws UserNotFoundException 
+     * @throws IsActiveException 
+     * @throws ScriptNotFoundException 
+     * @throws FileNotFoundException 
+     */
+    @Test
+    public final void testDeleteScript() throws DuplicateUserException, StorageException,
+            UserNotFoundException, QuotaExceededException, ScriptNotFoundException,
+            IsActiveException, FileNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+
+        // Delete existent inactive script
+        repo.putScript(user, scriptName, content);
+        repo.deleteScript(user, scriptName);
+        assertTrue("Script deletion failed", !new File(fs.getFile(SIEVE_ROOT), user + '/'
+                + scriptName).exists());
+
+        // Delete existent active script
+        repo.putScript(user, scriptName, content);
+        repo.setActive(user, scriptName);
+        boolean isActiveExceptionThrown = false;
+        try {
+            repo.deleteScript(user, scriptName);
+        } catch (IsActiveException ex) {
+            isActiveExceptionThrown = true;
+        }
+        assertTrue(isActiveExceptionThrown);
+
+        // Delete non existent script
+        boolean scriptNotFoundExceptionThrown = false;
+        try {
+            repo.deleteScript(user, "nonExistent");
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+    }
+
+    /**
+     * Test method for .
+     * @throws StorageException 
+     * @throws DuplicateUserException 
+     * @throws UserNotFoundException 
+     * @throws QuotaExceededException 
+     * @throws ScriptNotFoundException 
+     */
+    @Test
+    public final void testGetScript() throws DuplicateUserException, StorageException, UserNotFoundException,
+            QuotaExceededException, ScriptNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+
+        // Non existent script
+        boolean scriptNotFoundExceptionThrown = false;
+        try {
+            repo.getScript(user, scriptName);
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+
+        // Existent script
+        repo.putScript(user, scriptName, content);
+        assertEquals("Script content did not match", content, repo.getScript(user, scriptName));
+    }
+
+    /**
+     * Test method for .
+     * @throws DuplicateUserException 
+     * @throws QuotaExceededException 
+     * @throws UserNotFoundException 
+     * @throws StorageException 
+     * @throws ScriptNotFoundException 
+     */
+    @Test
+    public final void testHaveSpace() throws DuplicateUserException, UserNotFoundException, QuotaExceededException,
+            StorageException, ScriptNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        long defaultQuota = Long.MAX_VALUE - 1;
+        long userQuota = Long.MAX_VALUE / 2;
+        boolean quotaExceededExceptionThrown;
+
+        // No quota
+        repo.haveSpace(user, scriptName, defaultQuota + 1);
+
+        // Default quota
+        repo.setQuota(defaultQuota);
+        // Default quota - not exceeded
+        repo.haveSpace(user, scriptName, defaultQuota);
+        // Default quota - exceeded
+        quotaExceededExceptionThrown = false;
+        try {
+            repo.haveSpace(user, scriptName, defaultQuota + 1);
+        } catch (QuotaExceededException ex) {
+            quotaExceededExceptionThrown = true;
+        }
+        assertTrue(quotaExceededExceptionThrown);
+
+        // User quota file
+        repo.setQuota(user, userQuota);
+        // User quota - not exceeded
+        repo.haveSpace(user, scriptName, userQuota);
+        // User quota - exceeded
+        quotaExceededExceptionThrown = false;
+        try {
+            repo.haveSpace(user, scriptName, userQuota + 1);
+        } catch (QuotaExceededException ex) {
+            quotaExceededExceptionThrown = true;
+        }
+        assertTrue(quotaExceededExceptionThrown);
+
+        // Script replacement
+        String content = "01234567";
+        repo.putScript(user, scriptName, content);
+        // Script replacement, quota not exceeded
+        repo.haveSpace(user, scriptName, userQuota);
+        // Script replacement, quota exceeded
+        quotaExceededExceptionThrown = false;
+        try {
+            repo.haveSpace(user, scriptName, userQuota + 1);
+        } catch (QuotaExceededException ex) {
+            quotaExceededExceptionThrown = true;
+        }
+        assertTrue(quotaExceededExceptionThrown);
+
+        // Active script
+        repo.setActive(user, scriptName);
+        // User quota - not exceeded
+        repo.haveSpace(user, scriptName, userQuota);
+    }
+
+    /**
+     * Test method for .
+     * @throws StorageException 
+     * @throws DuplicateUserException 
+     * @throws UserNotFoundException 
+     * @throws QuotaExceededException 
+     * @throws ScriptNotFoundException 
+     */
+    @Test
+    public final void testListScripts() throws DuplicateUserException, StorageException, UserNotFoundException,
+            QuotaExceededException, ScriptNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+        String scriptName1 = "script1";
+        String content1 = "abcdefgh";
+
+        // No scripts
+        assertTrue(repo.listScripts(user).isEmpty());
+
+        // Inactive script
+        repo.putScript(user, scriptName, content);
+        List<ScriptSummary> summaries = repo.listScripts(user);
+        assertEquals(1, summaries.size());
+        assertEquals(scriptName, summaries.get(0).getName());
+        assertTrue(!summaries.get(0).isActive());
+
+        // Active script
+        repo.setActive(user, scriptName);
+        summaries = repo.listScripts(user);
+        assertEquals(1, summaries.size());
+        assertEquals(scriptName, summaries.get(0).getName());
+        assertTrue(summaries.get(0).isActive());
+
+        // One of each
+        repo.putScript(user, scriptName1, content1);
+        summaries = repo.listScripts(user);
+        assertEquals(2, summaries.size());
+        assertTrue(summaries.contains(new ScriptSummary(scriptName, true)));
+        assertTrue(summaries.contains(new ScriptSummary(scriptName1, false)));
+    }
+
+    /**
+     * Test method for .
+     * @throws DuplicateUserException 
+     * @throws QuotaExceededException 
+     * @throws StorageException 
+     * @throws UserNotFoundException 
+     * @throws FileNotFoundException 
+     */
+    @Test
+    public final void testPutScript() throws DuplicateUserException, UserNotFoundException,
+            StorageException, QuotaExceededException, FileNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+
+        // test new script
+        repo.putScript(user, scriptName, content);
+        assertTrue("Script creation failed", new File(fs.getFile(SIEVE_ROOT), user + '/'
+                + scriptName).exists());
+
+        // test script replacement
+        repo.putScript(user, scriptName, content);
+        assertTrue("Script replacement failed", new File(fs.getFile(SIEVE_ROOT), user + '/'
+                + scriptName).exists());
+
+        // test quota
+        repo.setQuota(content.length());
+        repo.putScript(user, scriptName, content);
+        repo.setQuota(content.length() - 1);
+        boolean quotaExceededExceptionThrown = false;
+        try {
+            repo.putScript(user, scriptName, content);
+        } catch (QuotaExceededException ex) {
+            quotaExceededExceptionThrown = true;
+        }
+        assertTrue(quotaExceededExceptionThrown);
+    }
+
+    /**
+     * Test method for .
+     * @throws StorageException 
+     * @throws DuplicateUserException 
+     * @throws DuplicateException 
+     * @throws IsActiveException 
+     * @throws UserNotFoundException 
+     * @throws ScriptNotFoundException 
+     * @throws QuotaExceededException 
+     */
+    @Test
+    public final void testRenameScript() throws DuplicateUserException, StorageException, UserNotFoundException,
+            IsActiveException, DuplicateException, ScriptNotFoundException, QuotaExceededException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+        String scriptName1 = "script1";
+
+        // Non existent script
+        boolean scriptNotFoundExceptionThrown = false;
+        try {
+            repo.renameScript(user, scriptName, scriptName1);
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+
+        // Existent script
+        repo.putScript(user, scriptName, content);
+        repo.renameScript(user, scriptName, scriptName1);
+        assertEquals("Script content did not match", content, repo.getScript(user, scriptName1));
+
+        // Propagate active script
+        repo.setActive(user, scriptName1);
+        repo.renameScript(user, scriptName1, scriptName);
+        assertEquals("Script content did not match", content, repo.getActive(user));
+
+        // Duplicate script
+        repo.setActive(user, "");
+        boolean duplicateExceptionThrown = false;
+        try {
+            repo.renameScript(user, scriptName, scriptName);
+        } catch (DuplicateException ex) {
+            duplicateExceptionThrown = true;
+        }
+        assertTrue(duplicateExceptionThrown);
+    }
+
+    /**
+     * Test method for .
+     * @throws StorageException 
+     * @throws DuplicateUserException 
+     * @throws QuotaExceededException 
+     * @throws UserNotFoundException 
+     * @throws ScriptNotFoundException 
+     */
+    @Test
+    public final void testGetActive() throws DuplicateUserException, StorageException, UserNotFoundException,
+            QuotaExceededException, ScriptNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+
+        // Non existent script
+        boolean scriptNotFoundExceptionThrown = false;
+        try {
+            repo.getActive(user);
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+
+        // Inactive script
+        repo.putScript(user, scriptName, content);
+        scriptNotFoundExceptionThrown = false;
+        try {
+            repo.getActive(user);
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+
+        // Active script
+        repo.setActive(user, scriptName);
+        assertEquals("Script content did not match", content, repo.getActive(user));
+    }
+
+    /**
+     * Test method for .
+     * @throws StorageException 
+     * @throws DuplicateUserException 
+     * @throws UserNotFoundException 
+     * @throws ScriptNotFoundException 
+     * @throws QuotaExceededException 
+     */
+    @Test
+    public final void testSetActive() throws DuplicateUserException, StorageException,
+            UserNotFoundException, ScriptNotFoundException, QuotaExceededException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+        String scriptName = "script";
+        String content = "01234567";
+        String scriptName1 = "script1";
+        String content1 = "abcdefgh";
+
+        // Non existent script
+        boolean scriptNotFoundExceptionThrown = false;
+        try {
+            repo.setActive(user, scriptName);
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+
+        // Existent script
+        repo.putScript(user, scriptName, content);
+        repo.setActive(user, scriptName);
+        assertEquals("Script content did not match", content, repo.getActive(user));
+
+        // Switch active script
+        repo.putScript(user, scriptName1, content1);
+        scriptNotFoundExceptionThrown = false;
+        repo.setActive(user, scriptName1);
+        assertEquals("Script content did not match", content1, repo.getActive(user));
+
+        // Disable active script
+        repo.setActive(user, "");
+        scriptNotFoundExceptionThrown = false;
+        try {
+            repo.getActive(user);
+        } catch (ScriptNotFoundException ex) {
+            scriptNotFoundExceptionThrown = true;
+        }
+        assertTrue(scriptNotFoundExceptionThrown);
+    }
+
+    @Test
+    public final void testAddUser() throws DuplicateUserException, StorageException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+
+        repo.addUser(user);
+        assertTrue(repo.hasUser(user));
+    }
+
+    @Test
+    public final void testRemoveUser() throws StorageException, DuplicateUserException, UserNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+
+        // Non existent user
+        boolean userNotFoundExceptionThrown = false;
+        try {
+            repo.removeUser(user);
+        } catch (UserNotFoundException ex) {
+            userNotFoundExceptionThrown = true;
+        }
+        assertTrue(userNotFoundExceptionThrown);
+
+        // Existent user
+        repo.addUser(user);
+        repo.removeUser(user);
+        assertTrue(!repo.hasUser(user));
+    }
+
+    @Test
+    public final void testHasUser() throws DuplicateUserException, StorageException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+
+        // Non existent user
+        assertTrue(!repo.hasUser(user));
+
+        // Existent user
+        repo.addUser(user);
+        assertTrue(repo.hasUser(user));
+    }
+
+    @Test
+    public final void testGetQuota() throws StorageException, QuotaNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+
+        // Non existent quota
+        boolean quotaNotFoundExceptionThrown = false;
+        try {
+            repo.getQuota();
+        } catch (QuotaNotFoundException ex) {
+            quotaNotFoundExceptionThrown = true;
+        }
+        assertTrue(quotaNotFoundExceptionThrown);
+
+        // Existent Quota
+        repo.setQuota(Long.MAX_VALUE);
+        assertEquals(Long.MAX_VALUE, repo.getQuota());
+    }
+
+    @Test
+    public final void testHasQuota() throws StorageException {
+        SieveRepository repo = new SieveFileRepository(fs);
+
+        // Non existent quota
+        assertTrue(!repo.hasQuota());
+
+        // Existent quota
+        repo.setQuota(Long.MAX_VALUE);
+        assertTrue(repo.hasQuota());
+    }
+
+    @Test
+    public final void testRemoveQuota() throws StorageException, QuotaNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+
+        // Non existent quota
+        boolean quotaNotFoundExceptionThrown = false;
+        try {
+            repo.removeQuota();
+        } catch (QuotaNotFoundException ex) {
+            quotaNotFoundExceptionThrown = true;
+        }
+        assertTrue(quotaNotFoundExceptionThrown);
+
+        // Existent quota
+        repo.setQuota(Long.MAX_VALUE);
+        repo.removeQuota();
+        assertTrue(!repo.hasQuota());
+    }
+
+    @Test
+    public final void testSetQuota() throws QuotaNotFoundException, StorageException {
+        SieveRepository repo = new SieveFileRepository(fs);
+
+        repo.setQuota(Long.MAX_VALUE);
+        assertEquals(Long.MAX_VALUE, repo.getQuota());
+    }
+
+    @Test
+    public final void testGetUserQuota() throws StorageException, QuotaNotFoundException, DuplicateUserException,
+            UserNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+
+        // Non existent quota
+        boolean quotaNotFoundExceptionThrown = false;
+        try {
+            repo.getQuota(user);
+        } catch (QuotaNotFoundException ex) {
+            quotaNotFoundExceptionThrown = true;
+        }
+        assertTrue(quotaNotFoundExceptionThrown);
+
+        // Existent Quota
+        repo.setQuota(user, Long.MAX_VALUE);
+        assertEquals(Long.MAX_VALUE, repo.getQuota(user));
+    }
+
+    @Test
+    public final void testHasUserQuota() throws StorageException, DuplicateUserException, UserNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+
+        // Non existent quota
+        assertTrue(!repo.hasQuota(user));
+
+        // Existent quota
+        repo.setQuota(user, Long.MAX_VALUE);
+        assertTrue(repo.hasQuota(user));
+    }
+
+    @Test
+    public final void testRemoveUserQuota() throws StorageException, QuotaNotFoundException, DuplicateUserException,
+            UserNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+
+        // Non existent quota
+        boolean quotaNotFoundExceptionThrown = false;
+        try {
+            repo.removeQuota(user);
+        } catch (QuotaNotFoundException ex) {
+            quotaNotFoundExceptionThrown = true;
+        }
+        assertTrue(quotaNotFoundExceptionThrown);
+
+        // Existent quota
+        repo.setQuota(user, Long.MAX_VALUE);
+        repo.removeQuota(user);
+        assertTrue(!repo.hasQuota(user));
+    }
+
+    @Test
+    public final void testSetUserQuota() throws QuotaNotFoundException, StorageException, DuplicateUserException,
+            UserNotFoundException {
+        SieveRepository repo = new SieveFileRepository(fs);
+        String user = "test";
+        repo.addUser(user);
+
+        repo.setQuota(user, Long.MAX_VALUE);
+        assertEquals(Long.MAX_VALUE, repo.getQuota(user));
+    }
+}



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