Author: rdonkin
Date: Fri Nov  9 04:46:58 2007
New Revision: 593512

URL: http://svn.apache.org/viewvc?rev=593512&view=rev
Log:
IMAP expression parser implementation. LIST and LSUB should now return accurate 
results.

Added:
    
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MailboxExpression.java
    
james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/MailboxExpressionTest.java
Modified:
    
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/ListResult.java
    
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/manager/MailboxManager.java
    
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListMailboxes.test
    
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListPlus.test
    
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalAuthenticatedStateTest.java
    
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalListingTest.java
    
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalSelectedInboxTest.java
    
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java

Modified: 
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/ListResult.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/ListResult.java?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/ListResult.java
 (original)
+++ 
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/ListResult.java
 Fri Nov  9 04:46:58 2007
@@ -25,6 +25,8 @@
 
 public interface ListResult {
     
+    public static final ListResult[] EMPTY_ARRAY = {};
+    
     /**
      * \Noinferiors, \Noselect, \Marked, \Unmarked 
      * TODO this should be done in a different way..

Modified: 
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/manager/MailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/manager/MailboxManager.java?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/manager/MailboxManager.java
 (original)
+++ 
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/manager/MailboxManager.java
 Fri Nov  9 04:46:58 2007
@@ -114,7 +114,8 @@
     void copyMessages(GeneralMailbox from, GeneralMessageSet set, String to) 
throws MailboxManagerException;
 
     /**
-     * 
+     * TODO: Expression requires parsing. Probably easier for the caller to 
+     * parse the expression into an object representation and use that instead.
      * @param base
      *            hierarchy starting point like #mail.user1 to list mailboxes 
of
      *            user1

Modified: 
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListMailboxes.test
URL: 
http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListMailboxes.test?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListMailboxes.test
 (original)
+++ 
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListMailboxes.test
 Fri Nov  9 04:46:58 2007
@@ -28,27 +28,27 @@
 
 # Empty 1st arg searches default context (#mail)
 C: 10 LIST "" listtest
-S: \* LIST \(\) \"\.\" listtest
+S: \* LIST \(\) \"\.\" "listtest"
 S: 10 OK LIST completed.
 
 # % returns all mailboxes matching
 C: a1 LIST "" %
 SUB {
-S: \* LIST \(\) \"\.\" listtest
-S: \* LIST \(\) \"\.\" listtest1
-S: \* LIST \(\) \"\.\" INBOX
+S: \* LIST \(\) \"\.\" "listtest"
+S: \* LIST \(\) \"\.\" "listtest1"
+S: \* LIST \(\) \"\.\" "INBOX"
 }
-S: a1 OK LIST completed
+S: a1 OK LIST completed.
 C: a2 LIST "" INBOX%
-S: \* LIST \(\) \"\.\" INBOX
-S: a2 OK LIST completed
+S: \* LIST \(\) \"\.\" "INBOX"
+S: a2 OK LIST completed.
 C: a3 LIST "" I%
-S: \* LIST \(\) \"\.\" INBOX
-S: a3 OK LIST completed
+S: \* LIST \(\) \"\.\" "INBOX"
+S: a3 OK LIST completed.
 C: a4 LIST "" l%
 SUB {
-S: \* LIST \(\) \"\.\" listtest
-S: \* LIST \(\) \"\.\" listtest1
+S: \* LIST \(\) \"\.\" "listtest"
+S: \* LIST \(\) \"\.\" "listtest1"
 }
 S: a4 OK LIST completed.
 
@@ -56,25 +56,25 @@
 # * returns all folders and subfolders
 C: b1 LIST "" *
 SUB {
-S: \* LIST \(\) \"\.\" listtest
-S: \* LIST \(\) \"\.\" listtest1
-S: \* LIST \(\) \"\.\" listtest.subfolder
-S: \* LIST \(\) \"\.\" listtest1.subfolder1
-S: \* LIST \(\) \"\.\" INBOX
+S: \* LIST \(\) \"\.\" "listtest"
+S: \* LIST \(\) \"\.\" "listtest1"
+S: \* LIST \(\) \"\.\" "listtest.subfolder"
+S: \* LIST \(\) \"\.\" "listtest1.subfolder1"
+S: \* LIST \(\) \"\.\" "INBOX"
 }
 S: b1 OK LIST completed.
 C: b2 LIST "" INBOX*
-S: \* LIST \(\) \"\.\" INBOX
+S: \* LIST \(\) \"\.\" "INBOX"
 S: b2 OK LIST completed.
 C: b3 LIST "" I*
-S: \* LIST \(\) \"\.\" INBOX
+S: \* LIST \(\) \"\.\" "INBOX"
 S: b3 OK LIST completed.
 C: b4 LIST "" l*
 SUB {
-S: \* LIST \(\) \"\.\" listtest
-S: \* LIST \(\) \"\.\" listtest1
-S: \* LIST \(\) \"\.\" listtest.subfolder
-S: \* LIST \(\) \"\.\" listtest1.subfolder1
+S: \* LIST \(\) \"\.\" "listtest"
+S: \* LIST \(\) \"\.\" "listtest1"
+S: \* LIST \(\) \"\.\" "listtest.subfolder"
+S: \* LIST \(\) \"\.\" "listtest1.subfolder1"
 }
 S: b4 OK LIST completed.
 

Modified: 
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListPlus.test
URL: 
http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListPlus.test?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListPlus.test
 (original)
+++ 
james/server/trunk/experimental-seda-imap-function/src/test/java/org/apache/james/test/functional/imap/scripts/ListPlus.test
 Fri Nov  9 04:46:58 2007
@@ -47,34 +47,36 @@
 S: \* LIST \(\) \"\.\" \"INBOX\"
 S: \* LIST \(\) \"\.\" \"funny\"
 }
-S: a1 OK List completed.
+S: a1 OK LIST completed.
 
 C: a2 list "" funny.%
 SUB {
 S: \* LIST \(\) \"\.\" \"funny.name with gaps\"
 S: \* LIST \(\) \"\.\" \"funny.name\"
 }
-S: a2 OK List completed.
+S: a2 OK LIST completed.
 
 C: a3 LIST "" *
 SUB {
 S: \* LIST \(\) \"\.\" \"listtest\"
+S: \* LIST \(\) \"\.\" \"listtest.subfolder\"
 S: \* LIST \(\) \"\.\" \"listtest1\"
+S: \* LIST \(\) \"\.\" \"listtest1.subfolder1\"
 S: \* LIST \(\) \"\.\" \"INBOX\"
 S: \* LIST \(\) \"\.\" \"funny\"
 S: \* LIST \(\) \"\.\" \"funny.name with gaps\"
 S: \* LIST \(\) \"\.\" \"funny.name with gaps\.more\"
 S: \* LIST \(\) \"\.\" \"funny.name\"
 }
-S: a3 OK List completed.
+S: a3 OK LIST completed.
 
 C: a4 LIST "" funny.*
 SUB {
-S: \* LIST \(\) \"\.\" "\funny.name with gaps\"
-S: \* LIST \(\) \"\.\" "\funny.name with gaps\.more\"
+S: \* LIST \(\) \"\.\" \"funny.name with gaps\"
+S: \* LIST \(\) \"\.\" \"funny.name with gaps\.more\"
 S: \* LIST \(\) \"\.\" \"funny.name\"
 }
-S: a4 OK List completed.
+S: a4 OK LIST completed.
 
 # Cleanup
 C: 15 DELETE "funny.name with gaps.more"

Modified: 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalAuthenticatedStateTest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalAuthenticatedStateTest.java?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalAuthenticatedStateTest.java
 (original)
+++ 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalAuthenticatedStateTest.java
 Fri Nov  9 04:46:58 2007
@@ -31,10 +31,6 @@
         // Check whether this is correct behaviour
     }
     
-    public void testListMailboxesUS() throws Exception {
-// TODO: fix bug - complete hierarchy returned
-    }
-    
     public void testAppendExpungeUS() throws Exception {
 //      TODO: EXPUNGE does not return correct flags
     }
@@ -47,10 +43,6 @@
 //      TODO: \recent flag is returned by FLAGS - specification seems 
ambiguoITALY on this
     }
     
-    public void testListMailboxesITALY() throws Exception {
-// TODO: fix bug - complete hierarchy returned
-    }
-    
     public void testAppendExpungeITALY() throws Exception {
 //      TODO: \recent flag is returned by FLAGS - specification seems 
ambiguoITALY on this
     }
@@ -62,10 +54,6 @@
     
     public void testSubscribeKOREA() throws Exception {
 //      TODO: \recent flag is returned by FLAGS - specification seems 
ambiguoKOREA on this
-    }
-        
-    public void testListMailboxesKOREA() throws Exception {
-// TODO: fix bug - complete hierarchy returned
     }
     
     public void testAppendExpungeKOREA() throws Exception {

Modified: 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalListingTest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalListingTest.java?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalListingTest.java
 (original)
+++ 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalListingTest.java
 Fri Nov  9 04:46:58 2007
@@ -26,9 +26,5 @@
     public ExperimentalListingTest() throws Exception {
         super(HostSystemFactory.createStandardImap());
     }
-    public void testListPlusUS() throws Exception {
-        // TODO: fix bug in Mailbox list API
-    }
-
     
 }

Modified: 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalSelectedInboxTest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalSelectedInboxTest.java?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalSelectedInboxTest.java
 (original)
+++ 
james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalSelectedInboxTest.java
 Fri Nov  9 04:46:58 2007
@@ -31,23 +31,13 @@
         //// scriptTest("ListNamespace", Locale.US);
     }
     
-    public void testListMailboxesUS() throws Exception {
-        //// scriptTest("ListMailboxes", Locale.US);
-    }
- 
     public void testSubscribeUS() throws Exception {
         //// scriptTest("Subscribe", Locale.US);
     }
-    
-    
+     
     public void testListNamespaceITALY() throws Exception {
         // scriptTest("ListNamespace", Locale.ITALY);
-    }
-    
-    public void testListMailboxesITALY() throws Exception {
-        // scriptTest("ListMailboxes", Locale.ITALY);
-    }
-   
+    }  
     
     public void testSubscribeITALY() throws Exception {
         // scriptTest("Subscribe", Locale.ITALY);
@@ -55,10 +45,6 @@
    
     public void testListNamespaceKOREA() throws Exception {
         // scriptTest("ListNamespace", Locale.KOREA);
-    }
-    
-    public void testListMailboxesKOREA() throws Exception {
-        // scriptTest("ListMailboxes", Locale.KOREA);
     }
     
     public void testSubscribeKOREA() throws Exception {

Added: 
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MailboxExpression.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MailboxExpression.java?rev=593512&view=auto
==============================================================================
--- 
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MailboxExpression.java
 (added)
+++ 
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MailboxExpression.java
 Fri Nov  9 04:46:58 2007
@@ -0,0 +1,281 @@
+/****************************************************************
+ * 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.mailboxmanager.torque;
+
+public class MailboxExpression {
+    
+    private final String base;
+    private final String expression;
+    private final char freeWildcard;
+    private final char localWildcard;
+    private final int expressionLength;
+    
+    /**
+     * Constructs an expression determining a set of mailbox names.
+     * @param base base reference name, not null
+     * @param expression mailbox match expression, not null
+     * @param freeWildcard matches any series of charaters
+     * @param localWildcard matches any sequence of characters
+     * up to the next hierarchy delimiter
+     */
+    public MailboxExpression(final String base, final String expression,
+                            final char freeWildcard, final char localWildcard) 
{
+        super();
+        if (base == null) {
+            this.base = "";
+        } else {
+            this.base = base;
+        }
+        if (expression == null) {
+            this.expression = "";
+        } else {
+            this.expression = expression;
+        }
+        expressionLength = this.expression.length();
+        this.freeWildcard = freeWildcard;
+        this.localWildcard = localWildcard;
+    }
+    
+    /**
+     * Gets the base reference name for the search.
+     * @return the base
+     */
+    public final String getBase() {
+        return base;
+    }
+
+    /**
+     * Gets the name search expression.
+     * This may contain wildcards.
+     * @return the expression
+     */
+    public final String getExpression() {
+        return expression;
+    }
+    
+    /**
+     * Gets wildcard character that matches any series of characters.
+     * @return the freeWildcard
+     */
+    public final char getFreeWildcard() {
+        return freeWildcard;
+    }
+
+    /**
+     * Gets wildacard character that matches any series of characters
+     * excluding hierarchy delimiters. Effectively, this means that
+     * it matches any sequence within a name part.
+     * @return the localWildcard
+     */
+    public final char getLocalWildcard() {
+        return localWildcard;
+    }
+
+    /**
+     * Is the given name a match for [EMAIL PROTECTED] #getExpression()}?
+     * @param name name to be matched
+     * @param hierarchyDelimiter mailbox hierarchy delimiter
+     * @return true if the given name matches this expression,
+     * false otherwise
+     */
+    public final boolean isExpressionMatch(String name, char 
hierarchyDelimiter) {
+        final boolean result;
+        if (isWild()) {
+            if (name == null)
+            {
+                result = false;                
+            } else {
+                result = isWildcardMatch(name, 0, 0, hierarchyDelimiter);
+            }
+        } else {
+            result = expression.equals(name);
+        }
+        return result;
+    }
+    
+    private final boolean isWildcardMatch(final String name, final int 
nameIndex, 
+            final int expressionIndex, final char hierarchyDelimiter) {
+        final boolean result;
+        if (expressionIndex < expressionLength) {
+            final char expressionNext = expression.charAt(expressionIndex);
+            if (expressionNext == freeWildcard) {
+                result = isFreeWildcardMatch(name, nameIndex, expressionIndex, 
hierarchyDelimiter);
+            } else if (expressionNext == localWildcard) {
+                result = isLocalWildcardMatch(name, nameIndex, 
expressionIndex, hierarchyDelimiter);
+            } else {
+                if (nameIndex < name.length()) {
+                    final char nameNext = name.charAt(nameIndex);
+                    if(nameNext == expressionNext) {
+                        result = isWildcardMatch(name, nameIndex +1, 
expressionIndex +1, hierarchyDelimiter);
+                    } else {
+                        result = false;
+                    }
+                } else {
+                    // more expression characters to match
+                    // but no more name
+                    result = false;
+                }
+            }
+        } else {
+            // no more expression characters to match
+            result = true;
+        }
+        return result;
+    }
+
+    private boolean isLocalWildcardMatch(final String name, final int 
nameIndex, final int expressionIndex, final char hierarchyDelimiter) {
+        final boolean result;
+        if (expressionIndex < expressionLength) {
+            final char expressionNext = expression.charAt(expressionIndex);
+            if (expressionNext == localWildcard) {
+                result = isLocalWildcardMatch(name, nameIndex, 
expressionIndex+1, hierarchyDelimiter);
+            } else if (expressionNext == freeWildcard) {
+                result = isFreeWildcardMatch(name, nameIndex, 
expressionIndex+1, hierarchyDelimiter);
+            } else {
+                boolean matchRest = false;
+                for (int i=nameIndex; i< name.length() ; i++) {
+                    final char tasteNextName = name.charAt(i);
+                    if (expressionNext == tasteNextName) {
+                        if (isLocalWildcardMatch(name, i, expressionIndex+1, 
hierarchyDelimiter)) {
+                            matchRest = true;
+                            break;
+                        }
+                    } else if (tasteNextName == hierarchyDelimiter) {
+                        matchRest = false;
+                        break;
+                    }
+                }
+                result = matchRest;
+            }
+        } else {
+            boolean containsDelimiter = false;
+            for (int i=nameIndex; i< name.length() ; i++) {
+                if (name.charAt(i) == hierarchyDelimiter) {
+                    containsDelimiter = true;
+                    break;
+                }
+            }
+            result = !containsDelimiter;
+        }
+        return result;
+    }
+
+    private boolean isWildcard(char character) {
+        return character == freeWildcard || character == localWildcard;
+    }
+    
+    private boolean isFreeWildcardMatch(final String name, final int 
nameIndex, final int expressionIndex, final char hierarchyDelimiter) {
+        final boolean result;
+        int nextNormal = expressionIndex;
+        while (nextNormal<expressionLength && 
isWildcard(expression.charAt(nextNormal))) {
+            nextNormal++;
+        }
+        if (nextNormal < expressionLength) {
+            final char expressionNextNormal = expression.charAt(nextNormal);
+            boolean matchRest = false;
+            for (int i=nameIndex; i< name.length() ; i++) {
+                final char tasteNextName = name.charAt(i);
+                if (expressionNextNormal == tasteNextName) {
+                    if (isWildcardMatch(name, i, nextNormal, 
hierarchyDelimiter)) {
+                        matchRest = true;
+                        break;
+                    }
+                }
+            }
+            result = matchRest;
+        } else {
+            // no more expression characters to match
+            result = true;
+        }
+        return result;
+    }
+    
+    /**
+     * Get combined name formed by adding expression to base using
+     * the given hierarchy delimiter.
+     * Note that the wildcards are retained in the combined name.
+     * @param hierarchyDelimiter delimiter for mailbox hierarchy
+     * @return [EMAIL PROTECTED] #getBase()} combined with [EMAIL PROTECTED] 
#getExpression()},
+     * not null
+     */
+    public String getCombinedName(char hierarchyDelimiter) {
+        final String result;
+        final int baseLength = base.length();
+        if (base != null && baseLength>0) {
+            final int lastChar = baseLength-1;
+            if(base.charAt(lastChar)==hierarchyDelimiter) {
+                if (expression != null && expression.length() > 0) {
+                    if (expression.charAt(0)==hierarchyDelimiter) {
+                        result = base + expression.substring(1);
+                    } else {
+                        result = base + expression;
+                    }
+                } else {
+                    result = base;
+                }
+            } else {
+                if (expression != null && expression.length() > 0) {
+                    if (expression.charAt(0)==hierarchyDelimiter) {
+                        result = base + expression;
+                    } else {
+                        result = base + hierarchyDelimiter + expression;
+                    }
+                } else {
+                    result = base;
+                }
+            }
+       } else {
+           result = expression;
+       }
+       return result; 
+    }
+    
+    /**
+     * Is this expression wild? 
+     * @return true if wildcard contained, false otherwise
+     */
+    public boolean isWild() {
+        return expression != null && (expression.indexOf(freeWildcard) >= 0 
+                || expression.indexOf(localWildcard) >= 0);
+    }
+
+    /**
+     * Renders a string sutable for logging.
+     * @return a <code>String</code> representation 
+     * of this object.
+     */
+    public String toString()
+    {
+        final String TAB = " ";
+        
+        String retValue = "";
+        
+        retValue = "MailboxExpression [ "
+            + "base = " + this.base + TAB
+            + "expression = " + this.expression + TAB
+            + "freeWildcard = " + this.freeWildcard + TAB
+            + "localWildcard = " + this.localWildcard + TAB
+            + " ]";
+    
+        return retValue;
+    }
+    
+    
+}

Modified: 
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java?rev=593512&r1=593511&r2=593512&view=diff
==============================================================================
--- 
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java
 (original)
+++ 
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java
 Fri Nov  9 04:46:58 2007
@@ -19,6 +19,7 @@
 
 package org.apache.james.mailboxmanager.torque;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
@@ -229,20 +230,20 @@
                 }
             }
         }
-        
-        // TODO handling of expressions is limited
-        
-        expression.replaceAll("\\*","%");
-        c.add(MailboxRowPeer.NAME,(Object)(expression),Criteria.LIKE);
+       
+        MailboxExpression mailboxExpression = new MailboxExpression(base, 
expression, '*', '%');
+        
c.add(MailboxRowPeer.NAME,(Object)(expression.replaceAll("\\*","%")),Criteria.LIKE);
         try {
             List mailboxRows=MailboxRowPeer.doSelect(c);
-            ListResult[] listResults=new ListResult[mailboxRows.size()];
-            int i=0;
+            List listResults=new ArrayList(mailboxRows.size());
             for (Iterator iter = mailboxRows.iterator(); iter.hasNext();) {
-                MailboxRow mailboxRow = (MailboxRow) iter.next();
-                listResults[i++]=new ListResultImpl(mailboxRow.getName(),".");
+                final MailboxRow mailboxRow = (MailboxRow) iter.next();
+                final String name = mailboxRow.getName();
+                if (mailboxExpression.isExpressionMatch(name, 
HIERARCHY_DELIMITER)) { 
+                    listResults.add(new ListResultImpl(name,"."));
+                }
             }
-            return listResults;    
+            return (ListResult[]) listResults.toArray(ListResult.EMPTY_ARRAY); 
   
         } catch (TorqueException e) {
             throw new MailboxManagerException(e);
         }

Added: 
james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/MailboxExpressionTest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/MailboxExpressionTest.java?rev=593512&view=auto
==============================================================================
--- 
james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/MailboxExpressionTest.java
 (added)
+++ 
james/server/trunk/torque-mailboxmanager-function/src/test/java/org/apache/james/mailboxmanager/torque/MailboxExpressionTest.java
 Fri Nov  9 04:46:58 2007
@@ -0,0 +1,264 @@
+/****************************************************************
+ * 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.mailboxmanager.torque;
+
+import junit.framework.TestCase;
+
+public class MailboxExpressionTest extends TestCase {
+
+    private static final String PART = "mailbox";
+    private static final String SECOND_PART = "sub";
+    private static final String BASE = "BASE";
+
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    private MailboxExpression create(String expression) {
+        return new MailboxExpression(BASE, expression, '*', '%');
+    }
+    
+    public void testIsWild() throws Exception {
+        assertTrue(create("*").isWild());
+        assertTrue(create("%").isWild());
+        assertTrue(create("One*").isWild());
+        assertTrue(create("*One").isWild());
+        assertTrue(create("A*A").isWild());
+        assertTrue(create("One%").isWild());
+        assertTrue(create("%One").isWild());
+        assertTrue(create("A%A").isWild());
+        assertFalse(create("").isWild());
+        assertFalse(create(null).isWild());
+        assertFalse(create("ONE").isWild());
+    }
+    
+    public void testCombinedNameEmptyPart() throws Exception {
+        MailboxExpression expression = new MailboxExpression(BASE, "", '*', 
'%');
+        assertEquals(BASE, expression.getCombinedName('.'));
+
+    } 
+    
+    public void testNullCombinedName() throws Exception {
+        MailboxExpression expression = new MailboxExpression(null, null, '*', 
'%');
+        assertNotNull(expression.getCombinedName('.'));
+
+    }
+    
+    public void testSimpleCombinedName() throws Exception {
+        MailboxExpression expression = create(PART);
+        assertEquals(BASE + "." + PART, expression.getCombinedName('.'));
+        assertEquals(BASE + "/" + PART, expression.getCombinedName('/'));
+    }
+    
+    public void testCombinedNamePartStartsWithDelimiter () throws Exception {
+        MailboxExpression expression = create("." + PART);
+        assertEquals(BASE + "." + PART, expression.getCombinedName('.'));
+        assertEquals(BASE + "/." + PART, expression.getCombinedName('/'));
+    }
+    
+    public void testCombinedNameBaseEndsWithDelimiter() throws Exception {
+        MailboxExpression expression = new MailboxExpression(BASE + '.', PART, 
'*', '%');
+        assertEquals(BASE + "." + PART, expression.getCombinedName('.'));
+        assertEquals(BASE + "./" + PART, expression.getCombinedName('/'));
+    }
+    
+    public void testCombinedNameBaseEndsWithDelimiterPartStarts() throws 
Exception {
+        MailboxExpression expression = new MailboxExpression(BASE + '.', '.' + 
PART, '*', '%');
+        assertEquals(BASE + "." + PART, expression.getCombinedName('.'));
+        assertEquals(BASE + "./." + PART, expression.getCombinedName('/'));
+    }
+    
+    public void testSimpleExpression() throws Exception {
+        MailboxExpression expression = create(PART);
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '/'));
+        assertFalse(expression.isExpressionMatch('.' + PART, '.'));
+        assertFalse(expression.isExpressionMatch(PART + '.', '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+    }
+    
+    public void testEmptyExpression() throws Exception {
+        MailboxExpression expression = create("");
+        assertTrue(expression.isExpressionMatch("", '.'));
+        assertTrue(expression.isExpressionMatch("", '/'));
+        assertFalse(expression.isExpressionMatch("whatever", '.'));
+        assertFalse(expression.isExpressionMatch(BASE + '.' + "whatever", 
'.'));
+        assertFalse(expression.isExpressionMatch(BASE + "whatever", '.'));
+    }
+    
+    public void testOnlyLocalWildcard() throws Exception {
+        MailboxExpression expression = create("%");
+        assertTrue(expression.isExpressionMatch("", '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART + SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(PART + '/' + SECOND_PART, 
'.'));
+    }
+    
+    
+    public void testOnlyFreeWildcard() throws Exception {
+        MailboxExpression expression = create("*");
+        assertTrue(expression.isExpressionMatch("", '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART + SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(PART + '/' + SECOND_PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+    }
+    
+    
+    public void testEndsWithLocalWildcard() throws Exception {
+        MailboxExpression expression = create(PART + '%');
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART + SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(PART + '/' + SECOND_PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+    }
+    
+    public void testStartsWithLocalWildcard() throws Exception {
+        MailboxExpression expression = create('%' + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + PART + 
'.' + SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+    }
+    
+    public void testContainsLocalWildcard() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + '%' + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '/' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + "w.hat.eve.r" + 
PART, '.'));
+    }
+    
+    
+    public void testEndsWithFreeWildcard() throws Exception {
+        MailboxExpression expression = create(PART + '*');
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART + SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(PART + '/' + SECOND_PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(PART + '.' + SECOND_PART, 
'.'));
+    }
+    
+    public void testStartsWithFreeWildcard() throws Exception {
+        MailboxExpression expression = create('*' + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+    }
+    
+    public void testContainsFreeWildcard() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + '*' + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '/' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + "w.hat.eve.r" + 
PART, '.'));
+    }
+    
+    public void testDoubleFreeWildcard() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + "**" + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '/' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + "w.hat.eve.r" + 
PART, '.'));
+    }
+    
+    public void testFreeLocalWildcard() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + "*%" + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '/' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + "w.hat.eve.r" + 
PART, '.'));
+    }
+    
+    public void testLocalFreeWildcard() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + "%*" + PART);
+        assertFalse(expression.isExpressionMatch("", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART, 
'.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '/' + PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + "w.hat.eve.r" + 
PART, '.'));
+    }
+    
+    public void testMultipleFreeWildcards() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + '*' + PART + '*' + 
SECOND_PART + "**");
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART + 
SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART + '.' 
+ SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + "tosh.bosh" + 
PART + "tosh.bosh" + SECOND_PART + "boshtosh", '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + 
PART.substring(1) + '.' + SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + 
PART.substring(1) + '.' + SECOND_PART + PART + '.' + SECOND_PART  + "toshbosh", 
'.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + 
PART.substring(1) + '.' + SECOND_PART + PART + '.' + SECOND_PART.substring(1), 
'.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + "tosh.bosh" + 
PART + "tosh.bosh" + PART + SECOND_PART + "boshtosh" + PART + SECOND_PART, 
'.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART.substring(1) + 
"tosh.bosh" + PART + "tosh.bosh" + SECOND_PART + PART.substring(1) + 
SECOND_PART + "boshtosh" + PART + SECOND_PART.substring(1), '.'));
+    }
+    
+    public void testSimpleMixedWildcards() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + '%' + PART + '*' + 
SECOND_PART);
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART + 
SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + PART + 
SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART + '.' + 
SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART + 
SECOND_PART + "Whatever", '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART + 
SECOND_PART + ".Whatever.", '.'));
+    }
+    
+    public void testFreeLocalMixedWildcards() throws Exception {
+        MailboxExpression expression = create(SECOND_PART + '*' + PART + '%' + 
SECOND_PART);
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART + 
SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART + 
SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + PART + '.' + 
SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + PART  + 
"Whatever" + SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + PART + 
SECOND_PART + ".Whatever.", '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART + 
SECOND_PART, '.'));
+        assertFalse(expression.isExpressionMatch(SECOND_PART + '.' + PART + 
SECOND_PART + '.' + SECOND_PART, '.'));
+        assertTrue(expression.isExpressionMatch(SECOND_PART + '.' + PART + '.' 
+ SECOND_PART + PART + SECOND_PART, '.'));
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to