You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2011/05/16 10:06:56 UTC

svn commit: r1103641 - in /james/mailbox/trunk: api/src/main/java/org/apache/james/mailbox/SearchQuery.java store/src/main/java/org/apache/james/mailbox/store/MessageSearches.java store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java

Author: norman
Date: Mon May 16 08:06:56 2011
New Revision: 1103641

URL: http://svn.apache.org/viewvc?rev=1103641&view=rev
Log:
Canonicalized the addresses into RFC 2822 normalized form when search for addresses. See MAILBOX-67

Modified:
    james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SearchQuery.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/MessageSearches.java
    james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SearchQuery.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SearchQuery.java?rev=1103641&r1=1103640&r2=1103641&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SearchQuery.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SearchQuery.java Mon May 16 08:06:56 2011
@@ -59,6 +59,13 @@ public class SearchQuery {
         
         
     }
+    
+    public static enum AddressType {
+        From,
+        To,
+        Cc,
+        Bcc
+    }
 
     public static int toCalendarType(DateResolution res) {
         int type;
@@ -229,6 +236,19 @@ public class SearchQuery {
     }
 
     /**
+     * Creates a filter matching messages whose Address header contains the given address. 
+     * The address header of the message MUST get canonicalized before try to match it.
+     * 
+     * @param type
+     * @param address
+     * @return <code>Criterion</code>
+     */
+    public static final Criterion address(AddressType type, String address) {       
+        return new HeaderCriterion(type.name(), new AddressOperator(address));
+    }
+
+    
+    /**
      * Creates a filter matching messages whose header value contains the given
      * value.
      * 
@@ -1297,6 +1317,70 @@ public class SearchQuery {
     public interface HeaderOperator extends Operator {
     }
 
+    public static final class AddressOperator implements HeaderOperator {
+        private final String address;
+
+        public AddressOperator(final String address) {
+            super();
+            this.address = address;
+        }
+
+        /**
+         * Gets the value to be searched for.
+         * 
+         * @return the value
+         */
+        public String getAddress() {
+            return address;
+        }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((address == null) ? 0 : address.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final AddressOperator other = (AddressOperator) obj;
+            if (address == null) {
+                if (other.address != null)
+                    return false;
+            } else if (!address.equals(other.address))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes in name = value
+         * format.
+         * 
+         * @return a <code>String</code> representation of this object.
+         */
+        public String toString() {
+            final String TAB = " ";
+
+            StringBuffer retValue = new StringBuffer();
+
+            retValue.append("AdressOperator ( ").append("address = ").append(this.address).append(TAB).append(" )");
+
+            return retValue.toString();
+        }
+    }
     /**
      * Contained value search.
      */

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/MessageSearches.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/MessageSearches.java?rev=1103641&r1=1103640&r2=1103641&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/MessageSearches.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/MessageSearches.java Mon May 16 08:06:56 2011
@@ -35,12 +35,18 @@ import javax.mail.Flags;
 
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.SearchQuery.AddressType;
 import org.apache.james.mailbox.SearchQuery.DateResolution;
 import org.apache.james.mailbox.UnsupportedSearchException;
 import org.apache.james.mailbox.SearchQuery.NumericRange;
 import org.apache.james.mailbox.store.mail.model.Header;
 import org.apache.james.mailbox.store.mail.model.Message;
 import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.field.address.Address;
+import org.apache.james.mime4j.field.address.AddressList;
+import org.apache.james.mime4j.field.address.Group;
+import org.apache.james.mime4j.field.address.Mailbox;
+import org.apache.james.mime4j.field.address.MailboxList;
 import org.apache.james.mime4j.field.datetime.DateTime;
 import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
 import org.apache.james.mime4j.field.datetime.parser.ParseException;
@@ -296,12 +302,57 @@ public class MessageSearches {
             result = matches((SearchQuery.ContainsOperator) operator, headerName, message);
         } else if (operator instanceof SearchQuery.ExistsOperator) {
             result = exists(headerName, message);
+        } else if (operator instanceof SearchQuery.AddressOperator) {
+            result = matchesAddress((SearchQuery.AddressOperator) operator, headerName, message);
         } else {
             throw new UnsupportedSearchException();
         }
         return result;
     }
-
+    
+    /**
+     * Match against a {@link AddressType} header
+     * 
+     * @param operator
+     * @param headerName
+     * @param message
+     * @return containsAddress
+     */
+    private boolean matchesAddress(final SearchQuery.AddressOperator operator,
+            final String headerName, final Message<?> message) {
+        final String text = operator.getAddress();
+        final List<Header> headers = message.getHeaders();
+        for (Header header:headers) {
+            final String name = header.getFieldName();
+            if (headerName.equalsIgnoreCase(name)) {
+                final String value = header.getValue();
+                try {
+                    AddressList aList = AddressList.parse(value);
+                    for (int i = 0; i < aList.size(); i++) {
+                        Address address = aList.get(i);
+                        if (address instanceof Mailbox) {
+                            System.out.println(((Mailbox) address).getAddress());
+                            if (((Mailbox) address).getAddress().contains(text)) {
+                                return true;
+                            }
+                        } else if (address instanceof Group) {
+                            MailboxList mList = ((Group) address).getMailboxes();
+                            for (int a = 0; i < mList.size(); a++) {
+                                if (mList.get(a).getAddress().contains(text)) {
+                                    return true;
+                                }                            
+                            }
+                        }
+                    }
+                } catch (org.apache.james.mime4j.field.address.parser.ParseException e) {
+                    log.debug("Unable to parse address from header " + headerName, e);
+                }
+                
+            }
+        }
+        return false;
+    }
+    
     private boolean exists(String headerName, Message<?> message) {
         boolean result = false;
         final List<Header> headers = message.getHeaders();

Modified: james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java?rev=1103641&r1=1103640&r2=1103641&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java (original)
+++ james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java Mon May 16 08:06:56 2011
@@ -31,6 +31,7 @@ import java.util.TimeZone;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.SearchQuery.AddressType;
 import org.apache.james.mailbox.SearchQuery.DateResolution;
 import org.apache.james.mailbox.store.MessageSearches;
 import org.apache.james.mailbox.store.mail.model.Message;
@@ -792,4 +793,13 @@ public class SearchUtilsTest {
         assertTrue(searches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(25, 3,
                 2007), DateResolution.Day),row, recent));
     }
+    
+    @Test
+    public void testShouldMatchAddressHeaderWithComments() throws Exception {
+        builder.header("To", "<user-from (comment)@ (comment) domain.org>");
+        Message<Long> row = builder.build();
+        assertTrue(searches.isMatch(SearchQuery.address(AddressType.To, "user-from@domain.org"), row, recent));
+        assertFalse(searches.isMatch(SearchQuery.address(AddressType.From, "user-from@domain.org"), row, recent));
+    }
+
 }



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