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 pp...@apache.org on 2012/02/21 22:05:03 UTC

svn commit: r1292019 [2/3] - in /james: imap/trunk/api/src/main/java/org/apache/james/imap/api/ imap/trunk/api/src/main/java/org/apache/james/imap/api/display/ imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/ imap/trunk/message/src...

Added: james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java?rev=1292019&view=auto
==============================================================================
--- james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java (added)
+++ james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java Tue Feb 21 21:05:02 2012
@@ -0,0 +1,223 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.imap.processor;
+
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapSessionState;
+import org.apache.james.imap.api.ImapSessionUtils;
+import org.apache.james.imap.api.message.response.StatusResponse;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapProcessor.Responder;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.message.request.DeleteACLRequest;
+import org.apache.james.imap.message.response.UnpooledStatusResponseFactory;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.MetaData;
+import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.EditMode;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.SimpleMailboxACL;
+import org.apache.james.mailbox.model.SimpleMailboxACL.Rfc4314Rights;
+import org.apache.james.mailbox.model.SimpleMailboxACL.SimpleMailboxACLEntryKey;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * DeleteACLProcessor Test.
+ * 
+ * @author Peter Palaga
+ */
+@RunWith(JMock.class)
+public class DeleteACLProcessorTest {
+
+    private static final String MAILBOX_NAME = ImapConstants.INBOX_NAME;
+    private static final String USER_1 = "user1";
+
+    ImapSession imapSessionStub;
+    MailboxManager mailboxManagerStub;
+    MailboxSession mailboxSessionStub;
+    MessageManager messageManagerStub;
+    MetaData metaDataStub;
+    Mockery mockery = new JUnit4Mockery();
+    DeleteACLRequest deleteACLRequest;
+    UnpooledStatusResponseFactory statusResponseFactory;
+    DeleteACLProcessor subject;
+    User user1Stub;
+    MailboxACLEntryKey user1Key;
+
+    private Expectations prepareRightsExpectations() throws MailboxException {
+        return new Expectations() {
+            {
+
+                allowing(imapSessionStub).getAttribute(ImapSessionUtils.MAILBOX_SESSION_ATTRIBUTE_SESSION_KEY);
+                will(returnValue(mailboxSessionStub));
+
+                allowing(imapSessionStub).getState();
+                will(returnValue(ImapSessionState.AUTHENTICATED));
+
+                allowing(mailboxSessionStub).getUser();
+                will(returnValue(user1Stub));
+
+                allowing(user1Stub).getUserName();
+                will(returnValue(USER_1));
+
+                allowing(mailboxManagerStub).startProcessingRequest(with(same(mailboxSessionStub)));
+                allowing(mailboxManagerStub).endProcessingRequest(with(same(mailboxSessionStub)));
+
+                allowing(messageManagerStub).getMetaData(with(any(Boolean.class)), with(same(mailboxSessionStub)), with(any(FetchGroup.class)));
+                will(returnValue(metaDataStub));
+
+            }
+        };
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        statusResponseFactory = new UnpooledStatusResponseFactory();
+        mailboxManagerStub = mockery.mock(MailboxManager.class);
+        subject = new DeleteACLProcessor(mockery.mock(ImapProcessor.class), mailboxManagerStub, statusResponseFactory);
+        imapSessionStub = mockery.mock(ImapSession.class);
+        mailboxSessionStub = mockery.mock(MailboxSession.class);
+        user1Stub = mockery.mock(User.class);
+        messageManagerStub = mockery.mock(MessageManager.class);
+        metaDataStub = mockery.mock(MetaData.class);
+
+        deleteACLRequest = new DeleteACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME, USER_1);
+
+        user1Key = new SimpleMailboxACLEntryKey(USER_1);
+    }
+    
+    @Test
+    public void testNoListRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(deleteACLRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testNoAdminRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(deleteACLRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testInexistentMailboxName() throws Exception {
+        Expectations expectations = prepareRightsExpectations();
+        
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.throwException(new MailboxNotFoundException(MAILBOX_NAME)));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(deleteACLRequest, responderMock, imapSessionStub);
+    }
+
+    
+    @Test
+    public void testDelete() throws MailboxException {
+        final MailboxACL acl = SimpleMailboxACL.OWNER_FULL_ACL;
+
+        Expectations expectations = prepareRightsExpectations();
+        
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+        
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        expectations.allowing(messageManagerStub).setRights(expectations.with(Expectations.equal(user1Key)), expectations.with(Expectations.equal(EditMode.REPLACE)), expectations.with(Expectations.aNull(MailboxACLRights.class)));
+
+        expectations.allowing(metaDataStub).getACL();
+        expectations.will(Expectations.returnValue(acl));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.OK)));
+            }
+        });
+
+        DeleteACLRequest r = new DeleteACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME, USER_1);
+        subject.doProcess(r, responderMock, imapSessionStub);
+    }
+
+}

Modified: james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java (original)
+++ james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java Tue Feb 21 21:05:02 2012
@@ -66,7 +66,7 @@ public class GetACLProcessorTest {
     MessageManager messageManagerStub;
     MetaData metaDataStub;
     Mockery mockery = new JUnit4Mockery();
-    GetACLRequest namespaceRequest;
+    GetACLRequest getACLRequest;
     UnpooledStatusResponseFactory statusResponseFactory;
     GetACLProcessor subject;
     User user1Stub;
@@ -108,7 +108,7 @@ public class GetACLProcessorTest {
         messageManagerStub = mockery.mock(MessageManager.class);
         metaDataStub = mockery.mock(MetaData.class);
 
-        namespaceRequest = new GetACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME);
+        getACLRequest = new GetACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME);
 
     }
 
@@ -131,7 +131,7 @@ public class GetACLProcessorTest {
             }
         });
 
-        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+        subject.doProcess(getACLRequest, responderMock, imapSessionStub);
 
     }
     
@@ -157,7 +157,7 @@ public class GetACLProcessorTest {
             }
         });
 
-        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+        subject.doProcess(getACLRequest, responderMock, imapSessionStub);
 
     }
     
@@ -177,7 +177,7 @@ public class GetACLProcessorTest {
             }
         });
 
-        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+        subject.doProcess(getACLRequest, responderMock, imapSessionStub);
     }
 
     @Test
@@ -211,7 +211,7 @@ public class GetACLProcessorTest {
             }
         });
 
-        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+        subject.doProcess(getACLRequest, responderMock, imapSessionStub);
     }
 
 }

Added: james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/ListRightsProcessorTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/ListRightsProcessorTest.java?rev=1292019&view=auto
==============================================================================
--- james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/ListRightsProcessorTest.java (added)
+++ james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/ListRightsProcessorTest.java Tue Feb 21 21:05:02 2012
@@ -0,0 +1,227 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.imap.processor;
+
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapSessionState;
+import org.apache.james.imap.api.ImapSessionUtils;
+import org.apache.james.imap.api.message.response.StatusResponse;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapProcessor.Responder;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.message.request.ListRightsRequest;
+import org.apache.james.imap.message.response.ListRightsResponse;
+import org.apache.james.imap.message.response.UnpooledStatusResponseFactory;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.MetaData;
+import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.SimpleMailboxACL;
+import org.apache.james.mailbox.model.SimpleMailboxACL.Rfc4314Rights;
+import org.apache.james.mailbox.model.SimpleMailboxACL.SimpleMailboxACLEntryKey;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * ListRightsProcessor Test.
+ * 
+ * @author Peter Palaga
+ */
+@RunWith(JMock.class)
+public class ListRightsProcessorTest {
+
+    private static final String MAILBOX_NAME = ImapConstants.INBOX_NAME;
+    private static final String USER_1 = "user1";
+
+    ImapSession imapSessionStub;
+    MailboxManager mailboxManagerStub;
+    MailboxSession mailboxSessionStub;
+    MessageManager messageManagerStub;
+    MetaData metaDataStub;
+    Mockery mockery = new JUnit4Mockery();
+    ListRightsRequest listRightsRequest;
+    UnpooledStatusResponseFactory statusResponseFactory;
+    ListRightsProcessor subject;
+    User user1Stub;
+    MailboxACLEntryKey user1Key;
+    MailboxACLRights[] listRights;
+
+    private Expectations prepareRightsExpectations() throws MailboxException {
+        return new Expectations() {
+            {
+
+                allowing(imapSessionStub).getAttribute(ImapSessionUtils.MAILBOX_SESSION_ATTRIBUTE_SESSION_KEY);
+                will(returnValue(mailboxSessionStub));
+
+                allowing(imapSessionStub).getState();
+                will(returnValue(ImapSessionState.AUTHENTICATED));
+
+                allowing(mailboxSessionStub).getUser();
+                will(returnValue(user1Stub));
+
+                allowing(user1Stub).getUserName();
+                will(returnValue(USER_1));
+
+                allowing(mailboxManagerStub).startProcessingRequest(with(same(mailboxSessionStub)));
+                allowing(mailboxManagerStub).endProcessingRequest(with(same(mailboxSessionStub)));
+
+                allowing(messageManagerStub).getMetaData(with(any(Boolean.class)), with(same(mailboxSessionStub)), with(any(FetchGroup.class)));
+                will(returnValue(metaDataStub));
+
+            }
+        };
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        statusResponseFactory = new UnpooledStatusResponseFactory();
+        mailboxManagerStub = mockery.mock(MailboxManager.class);
+        subject = new ListRightsProcessor(mockery.mock(ImapProcessor.class), mailboxManagerStub, statusResponseFactory);
+        imapSessionStub = mockery.mock(ImapSession.class);
+        mailboxSessionStub = mockery.mock(MailboxSession.class);
+        user1Stub = mockery.mock(User.class);
+        messageManagerStub = mockery.mock(MessageManager.class);
+        metaDataStub = mockery.mock(MetaData.class);
+
+        listRightsRequest = new ListRightsRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME, USER_1);
+
+        user1Key = new SimpleMailboxACLEntryKey(USER_1);
+        listRights = new MailboxACLRights[] {new Rfc4314Rights("ae"), new Rfc4314Rights("i"), new Rfc4314Rights("k")};
+    }
+    
+    @Test
+    public void testNoListRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(listRightsRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testNoAdminRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(listRightsRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testInexistentMailboxName() throws Exception {
+        Expectations expectations = prepareRightsExpectations();
+        
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.throwException(new MailboxNotFoundException(MAILBOX_NAME)));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(listRightsRequest, responderMock, imapSessionStub);
+    }
+
+    
+    @Test
+    public void testListRights() throws MailboxException {
+        final MailboxACL acl = SimpleMailboxACL.OWNER_FULL_ACL;
+
+        Expectations expectations = prepareRightsExpectations();
+        
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+        
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        expectations.allowing(messageManagerStub).listRigths(expectations.with(Expectations.equal(user1Key)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(listRights));
+
+        expectations.allowing(metaDataStub).getACL();
+        expectations.will(Expectations.returnValue(acl));
+
+        mockery.checking(expectations);
+
+        final ListRightsResponse response = new ListRightsResponse(MAILBOX_NAME, USER_1, listRights);
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(equal(response)));
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.OK)));
+            }
+        });
+
+        subject.doProcess(listRightsRequest, responderMock, imapSessionStub);
+    }
+
+}

Added: james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SetACLProcessorTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SetACLProcessorTest.java?rev=1292019&view=auto
==============================================================================
--- james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SetACLProcessorTest.java (added)
+++ james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SetACLProcessorTest.java Tue Feb 21 21:05:02 2012
@@ -0,0 +1,263 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.imap.processor;
+
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapSessionState;
+import org.apache.james.imap.api.ImapSessionUtils;
+import org.apache.james.imap.api.message.response.StatusResponse;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapProcessor.Responder;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.message.request.SetACLRequest;
+import org.apache.james.imap.message.response.UnpooledStatusResponseFactory;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.MetaData;
+import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.EditMode;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.SimpleMailboxACL;
+import org.apache.james.mailbox.model.SimpleMailboxACL.Rfc4314Rights;
+import org.apache.james.mailbox.model.SimpleMailboxACL.SimpleMailboxACLEntryKey;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * SetACLProcessor Test.
+ * 
+ * @author Peter Palaga
+ */
+@RunWith(JMock.class)
+public class SetACLProcessorTest {
+
+    private static final String MAILBOX_NAME = ImapConstants.INBOX_NAME;
+    private static final String USER_1 = "user1";
+    private static final String SET_RIGHTS = "aw";
+    private static final String UNSUPPORTED_RIGHT = "W";
+
+    ImapSession imapSessionStub;
+    MailboxManager mailboxManagerStub;
+    MailboxSession mailboxSessionStub;
+    MessageManager messageManagerStub;
+    MetaData metaDataStub;
+    Mockery mockery = new JUnit4Mockery();
+    SetACLRequest replaceACLRequest;
+    UnpooledStatusResponseFactory statusResponseFactory;
+    SetACLProcessor subject;
+    User user1Stub;
+    MailboxACLEntryKey user1Key;
+    MailboxACLRights setRights;
+
+    private Expectations prepareRightsExpectations() throws MailboxException {
+        return new Expectations() {
+            {
+
+                allowing(imapSessionStub).getAttribute(ImapSessionUtils.MAILBOX_SESSION_ATTRIBUTE_SESSION_KEY);
+                will(returnValue(mailboxSessionStub));
+
+                allowing(imapSessionStub).getState();
+                will(returnValue(ImapSessionState.AUTHENTICATED));
+
+                allowing(mailboxSessionStub).getUser();
+                will(returnValue(user1Stub));
+
+                allowing(user1Stub).getUserName();
+                will(returnValue(USER_1));
+
+                allowing(mailboxManagerStub).startProcessingRequest(with(same(mailboxSessionStub)));
+                allowing(mailboxManagerStub).endProcessingRequest(with(same(mailboxSessionStub)));
+
+                allowing(messageManagerStub).getMetaData(with(any(Boolean.class)), with(same(mailboxSessionStub)), with(any(FetchGroup.class)));
+                will(returnValue(metaDataStub));
+
+            }
+        };
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        statusResponseFactory = new UnpooledStatusResponseFactory();
+        mailboxManagerStub = mockery.mock(MailboxManager.class);
+        subject = new SetACLProcessor(mockery.mock(ImapProcessor.class), mailboxManagerStub, statusResponseFactory);
+        imapSessionStub = mockery.mock(ImapSession.class);
+        mailboxSessionStub = mockery.mock(MailboxSession.class);
+        user1Stub = mockery.mock(User.class);
+        messageManagerStub = mockery.mock(MessageManager.class);
+        metaDataStub = mockery.mock(MetaData.class);
+
+        replaceACLRequest = new SetACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME, USER_1, SET_RIGHTS);
+
+        user1Key = new SimpleMailboxACLEntryKey(USER_1);
+        setRights = new Rfc4314Rights(SET_RIGHTS);
+    }
+    
+    @Test
+    public void testUnsupportedRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.BAD)));
+            }
+        });
+
+        subject.doProcess(new SetACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME, USER_1, UNSUPPORTED_RIGHT), responderMock, imapSessionStub);
+
+    }
+
+    @Test
+    public void testNoListRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(replaceACLRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testNoAdminRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(replaceACLRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testInexistentMailboxName() throws Exception {
+        Expectations expectations = prepareRightsExpectations();
+        
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.throwException(new MailboxNotFoundException(MAILBOX_NAME)));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(replaceACLRequest, responderMock, imapSessionStub);
+    }
+
+    @Test
+    public void testAddRights() throws Exception {
+        testOp("+", EditMode.ADD);
+    }
+    
+    private void testOp(String prefix, EditMode editMode) throws MailboxException {
+        final MailboxACL acl = SimpleMailboxACL.OWNER_FULL_ACL;
+
+        Expectations expectations = prepareRightsExpectations();
+        
+        expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)), expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+        
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)), expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        expectations.allowing(messageManagerStub).setRights(expectations.with(Expectations.equal(user1Key)), expectations.with(Expectations.equal(editMode)), expectations.with(Expectations.equal(setRights)));
+
+        expectations.allowing(metaDataStub).getACL();
+        expectations.will(Expectations.returnValue(acl));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new StatusResponseTypeMatcher(StatusResponse.Type.OK)));
+            }
+        });
+
+        SetACLRequest r = new SetACLRequest("TAG", ImapCommand.anyStateCommand("Name"), MAILBOX_NAME, USER_1, prefix + SET_RIGHTS);
+        subject.doProcess(r, responderMock, imapSessionStub);
+    }
+    
+    @Test
+    public void testRemoveRights() throws Exception {
+        testOp("-", EditMode.REMOVE);
+    }
+
+    @Test
+    public void testReplaceRights() throws Exception {
+        testOp("", EditMode.REPLACE);
+    }
+
+}

Modified: james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java (original)
+++ james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java Tue Feb 21 21:05:02 2012
@@ -46,8 +46,12 @@ import org.apache.james.mailbox.MailboxS
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.exception.BadCredentialsException;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.UnsupportedRightException;
 import org.apache.james.mailbox.model.Content;
 import org.apache.james.mailbox.model.Headers;
+import org.apache.james.mailbox.model.MailboxACL.EditMode;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
 import org.apache.james.mailbox.model.MailboxMetaData;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MailboxQuery;
@@ -299,6 +303,21 @@ public class MailboxEventAnalyserTest {
                     return true;
                 }
 
+                @Override
+                public MailboxACLRights myRights(MailboxSession session) throws MailboxException {
+                    throw new UnsupportedOperationException("Not implemented");
+                }
+
+                @Override
+                public MailboxACLRights[] listRigths(MailboxACLEntryKey identifier, MailboxSession session) throws UnsupportedRightException {
+                    throw new UnsupportedOperationException("Not implemented");
+                }
+
+                @Override
+                public void setRights(MailboxACLEntryKey mailboxACLEntryKey, EditMode editMode, MailboxACLRights mailboxAclRights) throws UnsupportedRightException {
+                    throw new UnsupportedOperationException("Not implemented");
+                }
+
             };
         }
         
@@ -615,4 +634,11 @@ public class MailboxEventAnalyserTest {
         assertNotNull(iterator);
         assertFalse(iterator.hasNext());
     }
+
+    /* (non-Javadoc)
+     * @see org.apache.james.mailbox.MessageManager#myRights(org.apache.james.mailbox.MailboxSession)
+     */
+    public MailboxACLRights myRights(MailboxSession session) throws MailboxException {
+        return null;
+    }
 }

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java Tue Feb 21 21:05:02 2012
@@ -29,11 +29,16 @@ import javax.mail.Flags;
 
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedCriteriaException;
+import org.apache.james.mailbox.exception.UnsupportedRightException;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.EditMode;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mailbox.model.MessageResultIterator;
 import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
 import org.apache.james.mailbox.model.MessageResult.FetchGroup;
 
@@ -61,7 +66,7 @@ public interface MessageManager {
      * 
      * @param session
      * @return writable
-     * @throws MailboxException 
+     * @throws MailboxException
      * @deprecated use
      *             {@link #getMetaData(boolean, MailboxSession, org.apache.james.mailbox.MessageManager.MetaData.FetchGroup)}
      */
@@ -178,6 +183,51 @@ public interface MessageManager {
     public boolean hasRight(MailboxACLRight right, MailboxSession session) throws MailboxException;
 
     /**
+     * Returns the rights applicable to the user who has sent the current
+     * request.
+     * 
+     * @param session
+     * @return the rights applicable to the user who has sent the request,
+     *         returns {@link SimpleMailboxACL#NO_RIGHTS} if
+     *         {@code session.getUser()} is null.
+     * @throws UnsupportedRightException
+     */
+    public abstract MailboxACLRights myRights(MailboxSession session) throws MailboxException;
+
+    /**
+     * Computes a result suitable for the LISTRIGHTS IMAP command. The result is
+     * computed for this mailbox and the given {@code identifier}.
+     * 
+     * From RFC 4314 section 3.7:
+     * The first element of the resulting array contains the (possibly empty)
+     * set of rights the identifier will always be granted in the mailbox.
+     * Following this are zero or more right sets the identifier can be granted
+     * in the mailbox. Rights mentioned in the same set are tied together. The
+     * server MUST either grant all tied rights to the identifier in the mailbox
+     * or grant none.
+     * 
+     * The same right MUST NOT be listed more than once in the LISTRIGHTS
+     * command.
+     * 
+     * @param identifier
+     *            the identifier from the LISTRIGHTS command.
+     * @param session
+     * @return
+     * @throws UnsupportedRightException
+     */
+    public MailboxACLRights[] listRigths(MailboxACLEntryKey identifier, MailboxSession session) throws UnsupportedRightException;
+
+    /**
+     * TODO setRights.
+     * 
+     * @param identifier
+     * @param editMode
+     * @param mailboxAclRights
+     * @throws UnsupportedRightException
+     */
+    void setRights(MailboxACLEntryKey identifier, EditMode editMode, MailboxACLRights mailboxAclRights) throws UnsupportedRightException;
+
+    /**
      * Gets current meta data for the mailbox.<br>
      * Consolidates common calls together to allow improved performance.<br>
      * The meta-data returned should be immutable and represent the current

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/MailboxACLResolver.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/MailboxACLResolver.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/MailboxACLResolver.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/MailboxACLResolver.java Tue Feb 21 21:05:02 2012
@@ -24,6 +24,7 @@ import javax.mail.Flags;
 
 import org.apache.james.mailbox.exception.UnsupportedRightException;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
 
@@ -35,8 +36,8 @@ import org.apache.james.mailbox.model.Ma
  * to be granted to the identifier matching the user, one or more
  * implementation-defined identifiers matching groups that include the user,
  * and/or the identifier "anyone". How these rights are combined to determine
- * the users access is implementation defined. An implementation may choose,
- * for example, to use the union of the rights granted to the applicable
+ * the users access is implementation defined. An implementation may choose, for
+ * example, to use the union of the rights granted to the applicable
  * identifiers. An implementation may instead choose, for example, to use only
  * those rights granted to the most specific identifier present in the ACL. A
  * client can determine the set of rights granted to the logged-in user for a
@@ -55,7 +56,7 @@ public interface MailboxACLResolver {
      * @return
      * @throws UnsupportedRightException
      */
-    public abstract MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
+    public MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
 
     /**
      * Tells whether the given user has the given right granted on the basis of
@@ -88,31 +89,6 @@ public interface MailboxACLResolver {
     boolean hasRight(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACLRight right, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
 
     /**
-     * Computes the rights which apply to the given user and resource. Global ACL (if there is any) should be applied
-     * within this method.
-     * 
-     * @param requestUser
-     *            the user for whom the rights are computed, possibly
-     *            <code>null</code> when there is no authenticated user in the
-     *            given context.
-     * @param groupMembershipResolver
-     *            this resolver is used when checking whether any group rights
-     *            contained in resourceACL are applicable for the requestUser.
-     * @param resourceACL
-     *            the ACL defining the access right for the resource in
-     *            question.
-     * @param resourceOwner
-     *            this user name is used as a replacement for the "owner" place
-     *            holder in the resourceACL.
-     * @param resourceOwnerIsGroup
-     *            true if the resourceOwner is a group of users, false
-     *            otherwise.
-     * @return the rights applicable for the given user and resource.
-     * @throws UnsupportedRightException
-     */
-    public abstract MailboxACLRights listRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
-
-    /**
      * Maps the given {@code mailboxACLRights} to READ-WRITE and READ-ONLY
      * response codes.
      * 
@@ -151,4 +127,52 @@ public interface MailboxACLResolver {
      */
     public abstract boolean isReadWrite(MailboxACLRights mailboxACLRights, Flags sharedFlags) throws UnsupportedRightException;
 
+    /**
+     * Computes a result suitable for the LISTRIGHTS IMAP command. The result is
+     * computed regardless of mailbox. Therefore it should be viewed as a
+     * general default which may be further customised depending on the given
+     * mailbox.
+     * 
+     * @param key
+     *            the identifier from the LISTRIGHTS command
+     * @param groupMembershipResolver
+     * @param resourceOwner
+     *            the owner of the mailbox named in the LISTRIGHTS command. User
+     *            name or group name.
+     * @param resourceOwnerIsGroup
+     *            true if the {@code resourceOwner} is a group of users, false
+     *            otherwise.
+     * @return an array of {@link MailboxACLRights}. The first element is the
+     *         set of implicit (global) rights which does not need to be set
+     *         explicitly for the given identifier. Further elements are groups
+     *         of rights which can be set for the given identifier and resource.
+     * @throws UnsupportedRightException
+     */
+    public MailboxACLRights[] listRights(final MailboxACLEntryKey key, final GroupMembershipResolver groupMembershipResolver, final String resourceOwner, final boolean resourceOwnerIsGroup) throws UnsupportedRightException;
+
+    /**
+     * Computes the rights which apply to the given user and resource. Global
+     * ACL (if there is any) should be applied within this method.
+     * 
+     * @param requestUser
+     *            the user for whom the rights are computed, possibly
+     *            <code>null</code> when there is no authenticated user in the
+     *            given context.
+     * @param groupMembershipResolver
+     *            this resolver is used when checking whether any group rights
+     *            contained in resourceACL are applicable for the requestUser.
+     * @param resourceACL
+     *            the ACL defining the access right for the resource in
+     *            question.
+     * @param resourceOwner
+     *            this user name is used as a replacement for the "owner" place
+     *            holder in the resourceACL.
+     * @param resourceOwnerIsGroup
+     *            true if the resourceOwner is a group of users, false
+     *            otherwise.
+     * @return the rights applicable for the given user and resource.
+     * @throws UnsupportedRightException
+     */
+    public abstract MailboxACLRights resolveRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException;
+
 }

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/UnionMailboxACLResolver.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/UnionMailboxACLResolver.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/UnionMailboxACLResolver.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/acl/UnionMailboxACLResolver.java Tue Feb 21 21:05:02 2012
@@ -20,7 +20,9 @@
 
 package org.apache.james.mailbox.acl;
 
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -29,12 +31,13 @@ import javax.mail.Flags.Flag;
 
 import org.apache.james.mailbox.exception.UnsupportedRightException;
 import org.apache.james.mailbox.model.MailboxACL;
-import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLEntryKey;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLRight;
 import org.apache.james.mailbox.model.MailboxACL.MailboxACLRights;
 import org.apache.james.mailbox.model.MailboxACL.NameType;
+import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.model.SimpleMailboxACL.Rfc4314Rights;
+import org.apache.james.mailbox.model.SimpleMailboxACL.SimpleMailboxACLEntryKey;
 
 import com.sun.mail.mbox.Mailbox;
 
@@ -43,7 +46,7 @@ import com.sun.mail.mbox.Mailbox;
  * applicable identifiers. Inspired by RFC 4314 Section 2.
  * 
  * In
- * {@link UnionMailboxACLResolver#listRights(String, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver, MailboxACL, String, boolean)}
+ * {@link UnionMailboxACLResolver#resolveRights(String, org.apache.james.mailbox.MailboxACLResolver.GroupMembershipResolver, MailboxACL, String, boolean)}
  * all applicable negative and non-negative rights are union-ed separately and
  * the result is computed afterwards with
  * <code>nonNegativeUnion.except(negativeUnion)</code>.
@@ -62,6 +65,9 @@ public class UnionMailboxACLResolver imp
      */
     public static final MailboxACL DEFAULT_GLOBAL_USER_ACL = SimpleMailboxACL.OWNER_FULL_ACL;
 
+    private static final int POSITIVE_INDEX = 0;
+    private static final int NEGATIVE_INDEX = 1;
+
     private final MailboxACL groupGlobalACL;
     /**
      * Stores global ACL which is merged with ACL of every mailbox when
@@ -108,69 +114,147 @@ public class UnionMailboxACLResolver imp
     }
 
     /**
-     * Tells whether the given {@link MailboxACLEntryKey} is applicable for the
-     * given user. If the given key is a group key, the given
-     * {@link GroupMembershipResolver} is used to find out if the given user is
-     * a member of the key's group. If the given key is an "owner" key, it is
-     * effectively handled as if it was a {@code resourceOwner} key. To avoid
-     * clash between user and group names, {@code resourceOwnerIsGroup} must
-     * state explicitly if the given {@code resourceOwner} is a group.
+     * Tells whether the given {@code aclKey} {@link MailboxACLEntryKey} is
+     * applicable for the given {@code queryKey}.
+     * 
+     * There are two use cases for which this method was designed and tested:
+     * 
+     * (1) Calls from
+     * {@link #hasRight(String, GroupMembershipResolver, MailboxACLRight, MailboxACL, String, boolean)}
+     * and
+     * {@link #resolveRights(String, GroupMembershipResolver, MailboxACL, String, boolean)}
+     * in which the {@code queryKey} is a {@link NameType#user}.
+     * 
+     * (2) Calls from
+     * {@link #listRights(MailboxACLEntryKey, GroupMembershipResolver, String, boolean)}
+     * where {@code queryKey} can be anything including {@link NameType#user},
+     * {@link NameType#group} and all {@link NameType#special} identifiers.
+     * 
+     * Clearly the set of cases which this method has to handle in (1) is a
+     * proper subset of the cases handled in (2). See the javadoc on
+     * {@link #listRights(MailboxACLEntryKey, GroupMembershipResolver, String, boolean)}
+     * for more details.
      * 
-     * @param key
-     * @param user
+     * @param aclKey
+     * @param queryKey
      * @param groupMembershipResolver
      * @param resourceOwner
      * @param resourceOwnerIsGroup
      * @return
      */
-    protected boolean applies(MailboxACLEntryKey key, String user, GroupMembershipResolver groupMembershipResolver, String resourceOwner, boolean resourceOwnerIsGroup) {
-        final String keyName = key.getName();
-        final NameType keyNameType = key.getNameType();
-        if (MailboxACL.SpecialName.anybody.name().equals(keyName)) {
+    protected static boolean applies(MailboxACLEntryKey aclKey, MailboxACLEntryKey queryKey, GroupMembershipResolver groupMembershipResolver, String resourceOwner, boolean resourceOwnerIsGroup) {
+        final String aclKeyName = aclKey.getName();
+        final NameType aclKeyNameType = aclKey.getNameType();
+        if (MailboxACL.SpecialName.anybody.name().equals(aclKeyName)) {
             /* this works also for unauthenticated users */
             return true;
-        } else if (user != null) {
-            /* Authenticated users */
-            if (MailboxACL.SpecialName.authenticated.name().equals(keyName)) {
-                return true;
-            } else if (MailboxACL.SpecialName.owner.name().equals(keyName)) {
-                return (!resourceOwnerIsGroup && user.equals(resourceOwner)) || (resourceOwnerIsGroup && groupMembershipResolver.isMember(user, resourceOwner));
-            } else if (MailboxACL.NameType.user.equals(keyNameType)) {
-                return keyName.equals(user);
-            } else if (MailboxACL.NameType.group.equals(keyNameType)) {
-                return groupMembershipResolver.isMember(user, keyName);
+        } else if (queryKey != null) {
+            String queryUserOrGroupName = queryKey.getName();
+            switch (queryKey.getNameType()) {
+            case user:
+                /* Authenticated users */
+                switch (aclKeyNameType) {
+                case special:
+                    if (MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
+                        /* non null query user is viewed as authenticated */
+                        return true;
+                    } else if (MailboxACL.SpecialName.owner.name().equals(aclKeyName)) {
+                        return (!resourceOwnerIsGroup && queryUserOrGroupName.equals(resourceOwner)) || (resourceOwnerIsGroup && groupMembershipResolver.isMember(queryUserOrGroupName, resourceOwner));
+                    } else {
+                        /* should not happen unless the parent if is changed */
+                        throw new IllegalStateException("Unexpected " + MailboxACL.SpecialName.class.getName() + "." + aclKeyName);
+                    }
+                case user:
+                    return aclKeyName.equals(queryUserOrGroupName);
+                case group:
+                    return groupMembershipResolver.isMember(queryUserOrGroupName, aclKeyName);
+                default:
+                    throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
+                }
+            case group:
+                /* query is a group */
+                switch (aclKeyNameType) {
+                case special:
+                    if (MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
+                        /*
+                         * see the javadoc comment on listRights()
+                         */
+                        return true;
+                    } else if (MailboxACL.SpecialName.owner.name().equals(aclKeyName)) {
+                        return resourceOwnerIsGroup && queryUserOrGroupName.equals(resourceOwner);
+                    } else {
+                        /* should not happen unless the parent if is changed */
+                        throw new IllegalStateException("Unexpected " + MailboxACL.SpecialName.class.getName() + "." + aclKeyName);
+                    }
+                case user:
+                    /* query groups cannot match ACL users */
+                    return false;
+                case group:
+                    return aclKeyName.equals(queryUserOrGroupName);
+                default:
+                    throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
+                }
+            case special:
+                /* query is a special name */
+                switch (aclKeyNameType) {
+                case special:
+                    if (aclKeyName.equals(queryUserOrGroupName)) {
+                        /*
+                         * authenticated matches authenticated and owner matches
+                         * owner
+                         */
+                        return true;
+                    } else if (MailboxACL.SpecialName.owner.name().equals(queryUserOrGroupName) && MailboxACL.SpecialName.authenticated.name().equals(aclKeyName)) {
+                        /*
+                         * query owner matches authenticated because owner will
+                         * be resolved only if the user is authenticated
+                         */
+                        return true;
+                    } else {
+                        return false;
+                    }
+                case user:
+                case group:
+                    /* query specials cannot match ACL users or groups */
+                    return false;
+                default:
+                    throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + aclKeyNameType);
+                }
+            default:
+                throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + queryKey.getNameType());
             }
+        } else {
+            /* non-anybody ACL keys do not match non-authenticated queries */
+            return false;
         }
-        return false;
     }
 
     /**
-     * @see
-     * org.apache.james.mailbox.MailboxACLResolver#applyGlobalACL(org.apache
-     * .james.mailbox.MailboxACL, boolean)
+     * @see org.apache.james.mailbox.MailboxACLResolver#applyGlobalACL(org.apache
+     *      .james.mailbox.MailboxACL, boolean)
      */
     @Override
     public MailboxACL applyGlobalACL(MailboxACL resourceACL, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
         return resourceOwnerIsGroup ? resourceACL.union(groupGlobalACL) : resourceACL.union(userGlobalACL);
     }
 
-    /** 
-     * @see
-     * org.apache.james.mailbox.store.mail.MailboxACLResolver#hasRight(java.
-     * lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
-     * GroupMembershipResolver,
-     * org.apache.james.mailbox.MailboxACL.MailboxACLRight,
-     * org.apache.james.mailbox.MailboxACL, java.lang.String)
+    /**
+     * @see org.apache.james.mailbox.store.mail.MailboxACLResolver#hasRight(java.
+     *      lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
+     *      GroupMembershipResolver,
+     *      org.apache.james.mailbox.MailboxACL.MailboxACLRight,
+     *      org.apache.james.mailbox.MailboxACL, java.lang.String)
      */
     @Override
     public boolean hasRight(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACLRight right, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
+        final MailboxACLEntryKey queryKey = requestUser == null ? null : new SimpleMailboxACLEntryKey(requestUser, NameType.user, false);
         boolean result = false;
         Map<MailboxACLEntryKey, MailboxACLRights> entries = resourceOwnerIsGroup ? groupGlobalACL.getEntries() : userGlobalACL.getEntries();
         if (entries != null) {
             for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
                 final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
                 final MailboxACLEntryKey key = entry.getKey();
-                if (applies(key, requestUser, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
+                if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
                     if (key.isNegative()) {
                         return false;
                     } else {
@@ -186,7 +270,7 @@ public class UnionMailboxACLResolver imp
                 for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
                     final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
                     final MailboxACLEntryKey key = entry.getKey();
-                    if (applies(key, requestUser, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
+                    if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup) && entry.getValue().contains(right)) {
                         if (key.isNegative()) {
                             return false;
                         } else {
@@ -201,7 +285,8 @@ public class UnionMailboxACLResolver imp
     }
 
     /**
-     * @see org.apache.james.mailbox.acl.MailboxACLResolver#isReadWrite(org.apache.james.mailbox.model.MailboxACL.MailboxACLRights, javax.mail.Flags)
+     * @see org.apache.james.mailbox.acl.MailboxACLResolver#isReadWrite(org.apache.james.mailbox.model.MailboxACL.MailboxACLRights,
+     *      javax.mail.Flags)
      */
     @Override
     public boolean isReadWrite(MailboxACLRights mailboxACLRights, Flags sharedFlags) throws UnsupportedRightException {
@@ -212,14 +297,14 @@ public class UnionMailboxACLResolver imp
         /*
          * then go through shared flags. RFC 4314 section 4:
          * 
-         * Changing flags: STORE 
-         * 
-         * - the server MUST check if the user has "t" right 
+         * Changing flags: STORE
          * 
-         * - when the user modifies \Deleted flag "s" right 
+         * - the server MUST check if the user has "t" right
          * 
-         * - when the user modifies \Seen flag "w" right - for all other message flags.
+         * - when the user modifies \Deleted flag "s" right
          * 
+         * - when the user modifies \Seen flag "w" right - for all other message
+         * flags.
          */
         else if (sharedFlags != null) {
             if (sharedFlags.contains(Flag.DELETED) && mailboxACLRights.contains(Rfc4314Rights.t_DeleteMessages_RIGHT)) {
@@ -234,24 +319,96 @@ public class UnionMailboxACLResolver imp
         return false;
     }
 
-    /** 
-     * @see
-     * org.apache.james.mailbox.store.mail.MailboxACLResolver#rightsOf(java.
-     * lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
-     * GroupMembershipResolver, org.apache.james.mailbox.MailboxACL,
-     * java.lang.String)
+    /**
+     * The key point of this implementation is that it resolves everything what
+     * can be resolved. Let us explain what it means in particular for the
+     * implicit (global) rights included in the result:
+     * 
+     * (1) if {@code queryKey} is a user key, the rights included come from the
+     * following ACL entries:
+     * <ul>
+     * <li>the entry literally matching the given user name</li>
+     * <li>the entries of the groups of which the given user is a member</li>
+     * <li>if the given user is the owner of the given mailbox also the "owner"
+     * entry is included</li>
+     * <li>the "authenticated" entry</li>
+     * <li>the "anybody" entry</li>
+     * </ul>
+     * 
+     * (2) if {@code queryKey} is a group key, the rights included come from the
+     * following ACL entries:
+     * <ul>
+     * <li>the entry literally matching the given group name</li>
+     * <li>if the given group is the owner of the given mailbox also the "owner"
+     * entry is included</li>
+     * <li>the "authenticated" entry (*)</li>
+     * <li>the "anybody" entry</li>
+     * </ul>
+     * 
+     * (3) if {@code queryKey} is a special key, the rights included come from
+     * the following ACL entries:
+     * <ul>
+     * <li>the entry literally matching the given special name</li>
+     * <li>the "authenticated" entry if the {@code queryKey} is the "owner"
+     * query key (*)</li>
+     * <li>the "anybody" entry</li>
+     * </ul>
+     * 
+     * (*) This is the most questionable case: should "authenticated" ACL
+     * entries hold for group name queries? We say yes. Firstly, listing
+     * implicit rights for, say "group1", should inform which rights do not need
+     * to be set explicitly for the members of "group1". And secondly the group
+     * rights are actually queried and applied only for authenticated users. To
+     * put it in other words, the hasRight(user, right, ...) call can be
+     * performed only either with user == null (only "anybody" rights will
+     * apply) or with a user name which is there only after the user was
+     * authenticated.
+     * 
+     * @see org.apache.james.mailbox.acl.MailboxACLResolver#listRightsDefault(boolean)
      */
     @Override
-    public MailboxACL.MailboxACLRights listRights(String user, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
+    public MailboxACLRights[] listRights(final MailboxACLEntryKey queryKey, final GroupMembershipResolver groupMembershipResolver, final String resourceOwner, final boolean resourceOwnerIsGroup) throws UnsupportedRightException {
         MailboxACL.MailboxACLRights[] positiveNegativePair = { SimpleMailboxACL.NO_RIGHTS, SimpleMailboxACL.NO_RIGHTS };
 
-        listRights(user, groupMembershipResolver, userGlobalACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
+        MailboxACL userACL = resourceOwnerIsGroup ? groupGlobalACL : userGlobalACL;
+        resolveRights(queryKey, groupMembershipResolver, userACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
+
+        if (queryKey.isNegative()) {
+            return toListRightsArray(positiveNegativePair[NEGATIVE_INDEX]);
+        } else {
+            return toListRightsArray(positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]));
+        }
+    }
+
+    private static MailboxACLRights[] toListRightsArray(MailboxACLRights implicitRights) throws UnsupportedRightException {
+        List<MailboxACLRights> result = new ArrayList<MailboxACL.MailboxACLRights>(Rfc4314Rights.FIELD_COUNT);
+        result.add(implicitRights);
+        for (MailboxACLRight right : SimpleMailboxACL.FULL_RIGHTS) {
+            if (!implicitRights.contains(right)) {
+                result.add(new Rfc4314Rights(right));
+            }
+        }
+        return result.toArray(new MailboxACLRights[result.size()]);
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.MailboxACLResolver#rightsOf(java.
+     *      lang.String, org.apache.james.mailbox.store.mail.MailboxACLResolver.
+     *      GroupMembershipResolver, org.apache.james.mailbox.MailboxACL,
+     *      java.lang.String)
+     */
+    @Override
+    public MailboxACL.MailboxACLRights resolveRights(String requestUser, GroupMembershipResolver groupMembershipResolver, MailboxACL resourceACL, String resourceOwner, boolean resourceOwnerIsGroup) throws UnsupportedRightException {
+        MailboxACL.MailboxACLRights[] positiveNegativePair = { SimpleMailboxACL.NO_RIGHTS, SimpleMailboxACL.NO_RIGHTS };
+        final MailboxACLEntryKey queryKey = requestUser == null ? null : new SimpleMailboxACLEntryKey(requestUser, NameType.user, false);
+        MailboxACL userACL = resourceOwnerIsGroup ? groupGlobalACL : userGlobalACL;
+        resolveRights(queryKey, groupMembershipResolver, userACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
 
         if (resourceACL != null) {
-            listRights(user, groupMembershipResolver, resourceACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
+            resolveRights(queryKey, groupMembershipResolver, resourceACL.getEntries(), resourceOwner, resourceOwnerIsGroup, positiveNegativePair);
         }
 
-        return positiveNegativePair[0].except(positiveNegativePair[1]);
+        return positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]);
     }
 
     /**
@@ -265,16 +422,17 @@ public class UnionMailboxACLResolver imp
      * @param positiveNegativePair
      * @throws UnsupportedRightException
      */
-    private void listRights(String requestUser, GroupMembershipResolver groupMembershipResolver, final Map<MailboxACLEntryKey, MailboxACLRights> entries, String resourceOwner, boolean resourceOwnerIsGroup, MailboxACL.MailboxACLRights[] positiveNegativePair) throws UnsupportedRightException {
+    private void resolveRights(MailboxACLEntryKey queryKey, GroupMembershipResolver groupMembershipResolver, final Map<MailboxACLEntryKey, MailboxACLRights> entries, String resourceOwner, boolean resourceOwnerIsGroup, MailboxACL.MailboxACLRights[] positiveNegativePair)
+            throws UnsupportedRightException {
         if (entries != null) {
             for (Iterator<Map.Entry<MailboxACLEntryKey, MailboxACLRights>> it = entries.entrySet().iterator(); it.hasNext();) {
                 final Entry<MailboxACLEntryKey, MailboxACLRights> entry = it.next();
                 final MailboxACLEntryKey key = entry.getKey();
-                if (applies(key, requestUser, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup)) {
+                if (applies(key, queryKey, groupMembershipResolver, resourceOwner, resourceOwnerIsGroup)) {
                     if (key.isNegative()) {
-                        positiveNegativePair[1] = positiveNegativePair[1].union(entry.getValue());
+                        positiveNegativePair[NEGATIVE_INDEX] = positiveNegativePair[NEGATIVE_INDEX].union(entry.getValue());
                     } else {
-                        positiveNegativePair[0] = positiveNegativePair[0].union(entry.getValue());
+                        positiveNegativePair[POSITIVE_INDEX] = positiveNegativePair[POSITIVE_INDEX].union(entry.getValue());
                     }
                 }
             }

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedRightException.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedRightException.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedRightException.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/exception/UnsupportedRightException.java Tue Feb 21 21:05:02 2012
@@ -28,18 +28,25 @@ import org.apache.james.mailbox.model.Ma
  */
 public class UnsupportedRightException extends MailboxSecurityException {
 
+    private static final char INVALID_RIGHT = 0;
     private static final long serialVersionUID = 2959248897018370078L;
+    private char unsupportedRight = INVALID_RIGHT;
 
     public UnsupportedRightException() {
         super();
     }
+
+    public UnsupportedRightException(char right) {
+        super("Unsupported right flag '"+ right +"'.");
+        this.unsupportedRight  = right;
+    }
     
     public UnsupportedRightException(MailboxACLRight unsupportedRight) {
         this(unsupportedRight.getValue());
     }
     
-    public UnsupportedRightException(char rigthFlag) {
-        super("Unsupported right flag '"+ rigthFlag +"'.");
+    public char getUnsupportedRight() {
+        return unsupportedRight;
     }
 
 }

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java?rev=1292019&r1=1292018&r2=1292019&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java Tue Feb 21 21:05:02 2012
@@ -34,6 +34,13 @@ import org.apache.james.mailbox.exceptio
 public interface MailboxACL {
 
     /**
+     * SETACL command mode.
+     */
+    enum EditMode {
+        ADD, REMOVE, REPLACE
+    }
+
+    /**
      * The key used in {@link MailboxACL#getEntries()}. Implementations should
      * override {@link #hashCode()} and {@link #equals(Object)} in such a way
      * that all of {@link #getName()}, {@link #getNameType()} and
@@ -125,14 +132,6 @@ public interface MailboxACL {
     public interface MailboxACLRights extends Iterable<MailboxACLRight> {
 
         /**
-         * Tells whether the implementation supports the given right.
-         * 
-         * @param right
-         * @return true if this supports the given right.
-         */
-        boolean isSupported(MailboxACLRight right);
-
-        /**
          * Tells whether this contains the given right.
          * 
          * @param right
@@ -141,7 +140,7 @@ public interface MailboxACL {
          *             iff the given right is not supported.
          */
         boolean contains(MailboxACLRight right) throws UnsupportedRightException;
-        
+
         /**
          * Performs the set theoretic operation of relative complement of
          * toRemove MailboxACLRights in this MailboxACLRights.
@@ -157,7 +156,22 @@ public interface MailboxACL {
          * @return
          * @throws UnsupportedRightException
          */
-        public abstract MailboxACLRights except(MailboxACLRights toRemove) throws UnsupportedRightException;
+        public MailboxACLRights except(MailboxACLRights toRemove) throws UnsupportedRightException;
+
+        /**
+         * Tells if this set of rights is empty.
+         * 
+         * @return true if there are no rights in this set; false otherwise.
+         */
+        public boolean isEmpty();
+
+        /**
+         * Tells whether the implementation supports the given right.
+         * 
+         * @param right
+         * @return true if this supports the given right.
+         */
+        boolean isSupported(MailboxACLRight right);
 
         /**
          * Returns a serialized form of this {@link MailboxACLRights} as
@@ -185,7 +199,7 @@ public interface MailboxACL {
          */
         public abstract MailboxACLRights union(MailboxACLRights toAdd) throws UnsupportedRightException;
 
-    }
+    };
 
     /**
      * Allows distinguishing between users, groups and special names (see
@@ -203,6 +217,11 @@ public interface MailboxACL {
     };
 
     /**
+     * SETACL third argument prefix
+     */
+    public static final char ADD_RIGHTS_MARKER = '+';
+
+    /**
      * Marks groups when (de)serializing {@link MailboxACLEntryKey}s.
      * 
      * @see MailboxACLEntryKey#serialize()
@@ -217,6 +236,11 @@ public interface MailboxACL {
     public static final char DEFAULT_NEGATIVE_MARKER = '-';
 
     /**
+     * SETACL third argument prefix
+     */
+    public static final char REMOVE_RIGHTS_MARKER = '-';
+
+    /**
      * Performs the set theoretic operation of relative complement of toRemove
      * {@link MailboxACL} in this {@link MailboxACL}.
      * 
@@ -228,6 +252,10 @@ public interface MailboxACL {
      * toRemove parameter value in case the result would be equal to the
      * respective one of those.
      * 
+     * Implementations must ensure that the result does not contain entries with
+     * empty rigths. E.g. "user1:lr;user2:lrwt".except("user1:lr") should return
+     * "user2:lrwt" rather than "user1:;user2:lrwt"
+     * 
      * @param toRemove
      * @return
      * @throws UnsupportedRightException
@@ -235,6 +263,16 @@ public interface MailboxACL {
     MailboxACL except(MailboxACL toRemove) throws UnsupportedRightException;
 
     /**
+     * TODO except.
+     * 
+     * @param key
+     * @param toRemove
+     * @return
+     * @throws UnsupportedRightException
+     */
+    MailboxACL except(MailboxACLEntryKey key, MailboxACLRights toRemove) throws UnsupportedRightException;
+
+    /**
      * {@link Map} of entries.
      * 
      * @return the entries.
@@ -242,6 +280,27 @@ public interface MailboxACL {
     Map<MailboxACLEntryKey, MailboxACLRights> getEntries();
 
     /**
+     * Replaces the entry corresponding to the given {@code key} with
+     * {@code toAdd}link MailboxACLRights}.
+     * 
+     * Implementations must return a new unmodifiable instance of
+     * {@link MailboxACL}. However, implementations may decide to return this in
+     * case the result would be equal to it.
+     * 
+     * Implementations must ensure that the result does not contain entries with
+     * empty rigths. E.g. "user1:lr;user2:lrwt".replace("user1",
+     * MailboxACLRights.EMPTY) should return "user2:lrwt" rather than
+     * "user1:;user2:lrwt". The same result should be returned by
+     * "user1:lr;user2:lrwt".replace("user1", null).
+     * 
+     * @param key
+     * @param toAdd
+     * @return
+     * @throws UnsupportedRightException
+     */
+    MailboxACL replace(MailboxACLEntryKey key, MailboxACLRights toAdd) throws UnsupportedRightException;
+
+    /**
      * Performs the set theoretic operation of union of this {@link MailboxACL}
      * and toAdd {@link MailboxACL}.
      * 
@@ -261,4 +320,14 @@ public interface MailboxACL {
      */
     MailboxACL union(MailboxACL toAdd) throws UnsupportedRightException;
 
+    /**
+     * TODO union.
+     * 
+     * @param key
+     * @param toAdd
+     * @return
+     * @throws UnsupportedRightException
+     */
+    MailboxACL union(MailboxACLEntryKey key, MailboxACLRights toAdd) throws UnsupportedRightException;
+
 }



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