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/06/08 17:53:55 UTC

svn commit: r1133447 - in /james/mailbox/trunk: api/src/main/java/org/apache/james/mailbox/ store/src/main/java/org/apache/james/mailbox/store/search/ store/src/main/java/org/apache/james/mailbox/store/search/comparator/ store/src/main/java/org/apache/...

Author: norman
Date: Wed Jun  8 15:53:54 2011
New Revision: 1133447

URL: http://svn.apache.org/viewvc?rev=1133447&view=rev
Log:
This should now complete the SearchQuery Sort stuff. With this we can support MOST of the IMAP-EXTENSIONS. See MAILBOX-78

Added:
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderDisplayComparator.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/UpperCaseFilter.java
Modified:
    james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageMetaData.java
    james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SearchQuery.java
    james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SubscriptionManager.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/SearchUtil.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/AbstractHeaderComparator.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/CombinedComparator.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderMailboxComparator.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LenientImapSearchAnalyzer.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LuceneMessageSearchIndex.java
    james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/StrictImapSearchAnalyzer.java

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageMetaData.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageMetaData.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageMetaData.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageMetaData.java Wed Jun  8 15:53:54 2011
@@ -64,10 +64,6 @@ public interface MessageMetaData {
      * IMAP defines this as the time when the message has arrived to the server
      * (by smtp). Clients are also allowed to set the internalDate on append.
      * </p>
-     * <p>
-     * Is this Mail.getLastUpdates() for James delivery? Should we use
-     * MimeMessage.getReceivedDate()?
-     * </p>
      */
     Date getInternalDate();
 }

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=1133447&r1=1133446&r2=1133447&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 Wed Jun  8 15:53:54 2011
@@ -63,7 +63,6 @@ public class SearchQuery {
     public static enum AddressType {
         From,
         To,
-        Cc,
         Bcc
     }
     
@@ -72,24 +71,37 @@ public class SearchQuery {
         public static enum SortClause {
             
             /**
-             * Internal date and time of the message
+             * Internal date and time of the message (internaldate)
              */
             Arrival,
             
             /**
-             * addr-mailbox of the first "cc" address.
+             * addr-mailbox of the first "cc" address. 
+             * 
+             * This MUST BE converted to uppercase before doing the sort
              */
-            Cc,
+            MailboxCc,
             
             /**
              * addr-mailbox of the first "from" address.
+             * 
+             * This MUST BE converted to uppercase before doing the sort
+             */
+            MailboxFrom,
+            
+            /**
+             * addr-mailbox of the first "To" address
+             * 
+             * This MUST BE converted to uppercase before doing the sort
              */
-            From,
+            MailboxTo,
             
             /**
              * Base subject text.
+             * 
+             * This MUST BE converted to uppercase before doing the sort
              */
-            Subject,
+            BaseSubject,
             
             /**
              * Size of the message in octets.
@@ -97,14 +109,23 @@ public class SearchQuery {
             Size,
             
             /**
-             * addr-mailbox of the first "To" address
+             * 
              */
-            To,
+            SentDate,
             
             /**
+             * addr-name of the first "From" address
              * 
+             * This MUST BE converted to uppercase before doing the sort
              */
-            SentDate,
+            DisplayFrom,
+            
+            /**
+             * addr-name of the first "To" address
+             * 
+             * This MUST BE converted to uppercase before doing the sort
+             */
+            DisplayTo,
             
             /**
              * Uid of the message. This is the DEFAULT if no other is specified
@@ -350,6 +371,8 @@ public class SearchQuery {
      * Creates a filter matching messages whose header value contains the given
      * value.
      * 
+     * All to-compared Strings MUST BE converted to uppercase before doing so (this also include the search value)
+     *
      * @param headerName
      *            name of the header whose value will be compared, not null
      * @param value
@@ -368,6 +391,8 @@ public class SearchQuery {
     /**
      * Creates a filter matching messages with a header matching the given name.
      * 
+     * All to-compared Strings MUST BE converted to uppercase before doing so (this also include the search value)
+     * 
      * @param headerName
      *            name of the header whose value will be compared, not null
      * @return <code>Criterion</code>, not null
@@ -381,6 +406,8 @@ public class SearchQuery {
      * within the body or in the headers. Implementations may choose to ignore
      * mime parts which cannot be decoded to text.
      * 
+     * All to-compared Strings MUST BE converted to uppercase before doing so (this also include the search value)
+     * 
      * @param value
      *            search value
      * @return <code>Criterion</code>, not null
@@ -394,6 +421,8 @@ public class SearchQuery {
      * the body. Implementations may choose to ignore mime parts which cannot be
      * decoded to text.
      * 
+     * All to-compared Strings MUST BE converted to uppercase before doing so (this also include the search value)
+     * 
      * @param value
      *            search value
      * @return <code>Criterion</code>, not null

Modified: james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SubscriptionManager.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SubscriptionManager.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SubscriptionManager.java (original)
+++ james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/SubscriptionManager.java Wed Jun  8 15:53:54 2011
@@ -22,7 +22,9 @@ package org.apache.james.mailbox;
 import java.util.Collection;
 
 /**
- * Subscribes users.
+ * Subscribes mailboxes to users. This is only needed to implement if the Mailbox should be usable via
+ * IMAP. For POP3 only you don't need this at all.
+ * 
  */
 public interface SubscriptionManager extends RequestAware {
 

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java Wed Jun  8 15:53:54 2011
@@ -341,7 +341,7 @@ public class MessageSearches implements 
      */
     private static boolean matchesAddress(final SearchQuery.AddressOperator operator,
             final String headerName, final Message<?> message, Logger log) {
-        final String text = operator.getAddress().toLowerCase(Locale.US);
+        final String text = operator.getAddress().toUpperCase(Locale.ENGLISH);
         final List<Header> headers = message.getHeaders();
         for (Header header:headers) {
             final String name = header.getFieldName();
@@ -352,13 +352,13 @@ public class MessageSearches implements 
                     for (int i = 0; i < aList.size(); i++) {
                         Address address = aList.get(i);
                         if (address instanceof Mailbox) {
-                            if (((Mailbox) address).getEncodedString().toLowerCase(Locale.US).contains(text)) {
+                            if (((Mailbox) address).getEncodedString().toUpperCase(Locale.ENGLISH).contains(text)) {
                                 return true;
                             }
                         } else if (address instanceof Group) {
                             MailboxList mList = ((Group) address).getMailboxes();
                             for (int a = 0; a < mList.size(); a++) {
-                                if (mList.get(a).getEncodedString().toLowerCase(Locale.US).contains(text)) {
+                                if (mList.get(a).getEncodedString().toUpperCase(Locale.ENGLISH).contains(text)) {
                                     return true;
                                 }                            
                             }
@@ -574,7 +574,7 @@ public class MessageSearches implements 
     
 
     private static Calendar getGMT() {
-        return Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.UK);
+        return Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
     }
 
 

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/SearchUtil.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/SearchUtil.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/SearchUtil.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/SearchUtil.java Wed Jun  8 15:53:54 2011
@@ -22,8 +22,19 @@ import java.nio.charset.Charset;
 import java.util.Locale;
 
 import org.apache.james.mime4j.codec.DecoderUtil;
+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.address.parser.ParseException;
 import org.apache.james.mime4j.util.MimeUtil;
 
+/**
+ * Utility class which helps with extracting of data for searches
+ * 
+ *
+ */
 public class SearchUtil {
 
     private final static String FWD_PARENS = "(fwd)";
@@ -39,6 +50,139 @@ public class SearchUtil {
     
     private final static Charset UTF8 = Charset.forName("UTF8");
 
+    
+    /**
+     * Return the DISPLAY ADDRESS for the given {@link Mailbox}. 
+     * 
+     * See rfc5957 3. DISPLAY Sort Value for an Address for the details
+     * 
+     *     For the purposes of the sort criteria defined in this document, the
+     *     sort value for an [IMAP] address structure is defined as follows:
+     * <p>
+     *      o If the address structure's [IMAP] addr-name is non-NIL, apply the 
+     *        procedure from [RFC5255], Section 4.6.  (That is, decode any
+     *        RFC2047] encoded-words and convert the resulting character string
+     *        into a charset valid for the currently active [RFC4790] collation,
+     *        with a default of UTF-8.)  If the resulting octet string is not
+     *        the empty string, use it as the sort value for the address.
+     * </p>
+     * <p>
+     *      o  Otherwise, if the address structure's [IMAP] addr-mailbox and
+     *         [IMAP] addr-host are both non-NIL, the sort value for the address
+     *         is addr-mailbox@addr-host.
+     * </p>
+     * <p>
+     *      o  Otherwise, if the address structure's [IMAP] addr-mailbox is non-
+     *         NIL, the sort value for the address is its addr-mailbox.
+     * </p>
+     * <p>
+     *      o  If none of the above conditions are met, the sort value for the
+     *         address is the empty string.
+     * </p>
+     * @param mailbox
+     * @return display
+     */
+    public static String getDisplayAddress(Mailbox mailbox) {
+        String display = mailbox.getDisplayString();
+        if (display == null || display.length() < 1) {
+            String localPart = mailbox.getLocalPart();
+            String domainPart = mailbox.getDomain();
+            if (domainPart != null && domainPart.length() > 0 ) {
+                return localPart + "@" + domainPart;
+            } else {
+                return localPart;
+            }
+        }
+        return display;
+    }
+    
+    
+    /**
+     * Parse the headerValue and delegate to {@link #getDisplayAddress(Mailbox)}
+     * 
+     * If an {@link ParseException} was thrown, an empty String is returned
+     * 
+     * @param headerValue
+     * @return display
+     */
+    public static String getDisplayAddress(String headerValue) {
+        try {
+            AddressList addressList = AddressList.parse(MimeUtil.unfold(headerValue));
+            if (addressList != null && addressList.isEmpty() == false) {
+                Address address = addressList.get(0);
+                if (address instanceof Mailbox) {
+                    return getDisplayAddress((Mailbox) address);
+                } else if (address instanceof Group) {
+                    Group group = (Group) address;
+                    if (group != null) {
+                        MailboxList mList = group.getMailboxes();
+                        if (mList != null && mList.isEmpty() == false) {
+                            return getDisplayAddress(mList.get(0));
+                        }
+                    }
+                }
+            } 
+        } catch (ParseException e) {
+            // just catch and return an empty String
+        }
+      
+        
+        return "";
+    }
+    
+    /**
+     * Return addr-mailbox of the first "From" address.
+     * 
+     * See RFC5256 and RFC3501
+     * 
+     * Which is in fact the LocalPart
+     * @param mailbox
+     * @return addrMailbox
+     */
+    public static String getMailboxAddress(Mailbox mailbox) {
+        return mailbox.getLocalPart();
+    }
+    
+    
+    /**
+     * Parse the headerValue and delegate to {@link #getMailboxAddress(Mailbox)}
+     * 
+     * If an {@link ParseException} was thrown, an empty String is returned
+     * 
+     * @param headerValue
+     * @return mailbox
+     */
+    public static String getMailboxAddress(String headerValue) {
+        try {
+            AddressList aList = AddressList.parse(headerValue);
+            for (int i = 0; i < aList.size(); i++) {
+                Address address = aList.get(i);
+                if (address instanceof Mailbox) {
+                    Mailbox m = (Mailbox) address;
+                    String mailboxName = m.getLocalPart();
+                    if (mailboxName == null) {
+                        mailboxName ="";
+                    }
+                    return mailboxName;
+                } else if (address instanceof Group) {
+                    MailboxList mList = ((Group) address).getMailboxes();
+                    for (int a = 0; a < mList.size(); ) {
+                        String mailboxName = mList.get(a).getLocalPart();
+                        if (mailboxName == null) {
+                            mailboxName ="";
+                        }
+                        return mailboxName;                         
+                    }
+                }
+            }
+
+        } catch (org.apache.james.mime4j.field.address.parser.ParseException e) {
+            // Just catch and return an empty string
+        }
+        return "";
+    }
+    
+    
     /**
      * Extract the base subject from the given subject. 
      * 

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/AbstractHeaderComparator.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/AbstractHeaderComparator.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/AbstractHeaderComparator.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/AbstractHeaderComparator.java Wed Jun  8 15:53:54 2011
@@ -28,13 +28,17 @@ import org.apache.james.mailbox.store.ma
 
 public abstract class AbstractHeaderComparator implements Comparator<Message<?>>{
 
+    public final static String FROM ="from";
+    public final static String TO ="to";
+    public final static String CC ="cc";
+
     protected String getHeaderValue(String headerName, Message<?> message) {
         final List<Header> headers = message.getHeaders();
         for (Header header:headers) {
             final String name = header.getFieldName();
             if (headerName.equalsIgnoreCase(name)) {
                 final String value = header.getValue();
-                return value.toLowerCase(Locale.US);
+                return value.toUpperCase(Locale.ENGLISH);
             }
         }
         return "";

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/CombinedComparator.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/CombinedComparator.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/CombinedComparator.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/CombinedComparator.java Wed Jun  8 15:53:54 2011
@@ -63,19 +63,19 @@ public class CombinedComparator implemen
             case Arrival:
                 comparator = InternalDateComparator.internalDate(reverse);
                 break;
-            case Cc:
+            case MailboxCc:
                 comparator = HeaderMailboxComparator.cc(reverse);
                 break;
-            case From:
+            case MailboxFrom:
                 comparator = HeaderMailboxComparator.from(reverse);
                 break;
             case Size:
                 comparator = SizeComparator.size(reverse);
                 break;
-            case Subject:
+            case BaseSubject:
                 comparator = BaseSubjectComparator.baseSubject(reverse);
                 break;
-            case To:
+            case MailboxTo:
                 comparator = HeaderMailboxComparator.to(reverse);
                 break;
             case Uid:
@@ -83,6 +83,12 @@ public class CombinedComparator implemen
                 break;
             case SentDate: 
                 comparator = SentDateComparator.sentDate(reverse);
+            case DisplayFrom: 
+                comparator = HeaderDisplayComparator.from(reverse);
+                break;
+            case DisplayTo:
+                comparator = HeaderDisplayComparator.to(reverse);
+                break;
             default:
                 break;
             }

Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderDisplayComparator.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderDisplayComparator.java?rev=1133447&view=auto
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderDisplayComparator.java (added)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderDisplayComparator.java Wed Jun  8 15:53:54 2011
@@ -0,0 +1,67 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.mailbox.store.search.comparator;
+
+import java.util.Comparator;
+
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.search.SearchUtil;
+
+public class HeaderDisplayComparator extends AbstractHeaderComparator{
+
+
+    private final static Comparator<Message<?>> FROM_COMPARATOR = new HeaderDisplayComparator(FROM);
+    private final static Comparator<Message<?>> REVERSE_FROM_COMPARATOR = new ReverseComparator(FROM_COMPARATOR);
+
+
+    private final static Comparator<Message<?>> TO_COMPARATOR = new HeaderDisplayComparator(TO);
+    private final static Comparator<Message<?>> REVERSE_TO_COMPARATOR = new ReverseComparator(TO_COMPARATOR);
+
+    
+    private String headerName;
+
+    public HeaderDisplayComparator(String headerName) {
+        this.headerName = headerName;
+    }
+    
+    @Override
+    public int compare(Message<?> o1, Message<?> o2) {
+        String display1 = SearchUtil.getDisplayAddress(getHeaderValue(headerName, o1));
+        String display2 = SearchUtil.getDisplayAddress(getHeaderValue(headerName, o2));
+        return display1.compareToIgnoreCase(display2);
+    }
+
+    
+    public static Comparator<Message<?>> from(boolean reverse) {
+        if (reverse) {
+            return REVERSE_FROM_COMPARATOR;
+        } else {
+            return FROM_COMPARATOR;
+        }
+    }
+
+    
+    public static Comparator<Message<?>> to(boolean reverse) {
+        if (reverse) {
+            return REVERSE_TO_COMPARATOR;
+        } else {
+            return TO_COMPARATOR;
+        }
+    }
+}

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderMailboxComparator.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderMailboxComparator.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderMailboxComparator.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/comparator/HeaderMailboxComparator.java Wed Jun  8 15:53:54 2011
@@ -21,26 +21,22 @@ package org.apache.james.mailbox.store.s
 import java.util.Comparator;
 
 import org.apache.james.mailbox.store.mail.model.Message;
-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.mailbox.store.search.SearchUtil;
 
 public class HeaderMailboxComparator extends AbstractHeaderComparator{
 
     private final String headerName;
 
-    private final static Comparator<Message<?>> FROM = new HeaderMailboxComparator("from");
-    private final static Comparator<Message<?>> REVERSE_FROM = new ReverseComparator(FROM);
+    private final static Comparator<Message<?>> FROM_COMPARATOR = new HeaderMailboxComparator(FROM);
+    private final static Comparator<Message<?>> REVERSE_FROM_COMPARATOR = new ReverseComparator(FROM_COMPARATOR);
 
 
-    private final static Comparator<Message<?>> TO = new HeaderMailboxComparator("to");
-    private final static Comparator<Message<?>> REVERSE_TO = new ReverseComparator(TO);
+    private final static Comparator<Message<?>> TO_COMPARATOR = new HeaderMailboxComparator(TO);
+    private final static Comparator<Message<?>> REVERSE_TO_COMPARATOR = new ReverseComparator(TO_COMPARATOR);
 
 
-    private final static Comparator<Message<?>> CC = new HeaderMailboxComparator("cc");
-    private final static Comparator<Message<?>> REVERSE_CC = new ReverseComparator(CC);
+    private final static Comparator<Message<?>> CC_COMPARATOR = new HeaderMailboxComparator(CC);
+    private final static Comparator<Message<?>> REVERSE_CC_COMPARATOR = new ReverseComparator(CC_COMPARATOR);
 
     
     public HeaderMailboxComparator(String headerName) {
@@ -49,64 +45,35 @@ public class HeaderMailboxComparator ext
     
     @Override
     public int compare(Message<?> o1, Message<?> o2) {
-        String mailbox1 = getMailbox(headerName, o1);
-        String mailbox2 = getMailbox(headerName, o2);
+        String mailbox1 = SearchUtil.getMailboxAddress(getHeaderValue(headerName, o1));
+        String mailbox2 = SearchUtil.getMailboxAddress(getHeaderValue(headerName, o2));
 
-        return mailbox1.compareTo(mailbox2);
+        return mailbox1.compareToIgnoreCase(mailbox2);
     }
     
-    
-    private String getMailbox(String headerName, Message<?> message) {
-        try {
-            AddressList aList = AddressList.parse(getHeaderValue(headerName, message));
-            for (int i = 0; i < aList.size(); i++) {
-                Address address = aList.get(i);
-                if (address instanceof Mailbox) {
-                    Mailbox m = (Mailbox) address;
-                    String mailboxName = m.getName();
-                    if (mailboxName == null) {
-                        mailboxName ="";
-                    }
-                    return mailboxName;
-                } else if (address instanceof Group) {
-                    MailboxList mList = ((Group) address).getMailboxes();
-                    for (int a = 0; a < mList.size(); ) {
-                        String mailboxName = mList.get(a).getName();
-                        if (mailboxName == null) {
-                            mailboxName ="";
-                        }
-                        return mailboxName;                         
-                    }
-                }
-            }
 
-        } catch (org.apache.james.mime4j.field.address.parser.ParseException e) {
-            return "";
-        }
-        return "";
-    }
     
     public static Comparator<Message<?>> from(boolean reverse) {
         if (reverse) {
-            return REVERSE_FROM;
+            return REVERSE_FROM_COMPARATOR;
         } else {
-            return FROM;
+            return FROM_COMPARATOR;
         }
     }
     
     public static Comparator<Message<?>> cc(boolean reverse) {
         if (reverse) {
-            return REVERSE_CC;
+            return REVERSE_CC_COMPARATOR;
         } else {
-            return CC;
+            return CC_COMPARATOR;
         }
     }
     
     public static Comparator<Message<?>> to(boolean reverse) {
         if (reverse) {
-            return REVERSE_TO;
+            return REVERSE_TO_COMPARATOR;
         } else {
-            return TO;
+            return TO_COMPARATOR;
         }
     }
 }

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LenientImapSearchAnalyzer.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LenientImapSearchAnalyzer.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LenientImapSearchAnalyzer.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LenientImapSearchAnalyzer.java Wed Jun  8 15:53:54 2011
@@ -22,7 +22,6 @@ import java.io.Reader;
 
 
 import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.LowerCaseFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.WhitespaceTokenizer;
 import org.apache.lucene.analysis.shingle.ShingleFilter;
@@ -50,6 +49,6 @@ public final class LenientImapSearchAnal
     
     @Override
     public TokenStream tokenStream(String arg0, Reader reader) {
-        return new ShingleFilter(new LowerCaseFilter(Version.LUCENE_31, new WhitespaceTokenizer(Version.LUCENE_31, reader)), 2, maxTokenLength);
+        return new ShingleFilter(new UpperCaseFilter(new WhitespaceTokenizer(Version.LUCENE_31, reader)), 2, maxTokenLength);
     }
 }

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LuceneMessageSearchIndex.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LuceneMessageSearchIndex.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LuceneMessageSearchIndex.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/LuceneMessageSearchIndex.java Wed Jun  8 15:53:54 2011
@@ -158,7 +158,7 @@ public class LuceneMessageSearchIndex<Id
     public final static String TO_FIELD ="to";
     
     public final static String FIRST_TO_MAILBOX_NAME_FIELD ="firstToMailboxName";
-
+    public final static String FIRST_TO_MAILBOX_DISPLAY_FIELD ="firstToMailboxDisplay";
 
     /**
      * {@link Field} which will contain the CC-Address of the message
@@ -166,11 +166,6 @@ public class LuceneMessageSearchIndex<Id
     public final static String CC_FIELD ="cc";
 
     public final static String FIRST_CC_MAILBOX_NAME_FIELD ="firstCcMailboxName";
-
-    /**
-     * {@link Field} which will contain the BCC-Address of the message
-     */
-    public final static String BCC_FIELD ="bcc";
     
 
     /**
@@ -179,6 +174,7 @@ public class LuceneMessageSearchIndex<Id
     public final static String FROM_FIELD ="from";
     
     public final static String FIRST_FROM_MAILBOX_NAME_FIELD ="firstFromMailboxName";
+    public final static String FIRST_FROM_MAILBOX_DISPLAY_FIELD ="firstFromMailboxDisplay";
 
     public final static String BASE_SUBJECT_FIELD = "baseSubject";
     
@@ -253,6 +249,7 @@ public class LuceneMessageSearchIndex<Id
     private final static SortField FIRST_FROM_MAILBOX_SORT = new SortField(FIRST_FROM_MAILBOX_NAME_FIELD, SortField.LONG);
     private final static SortField FIRST_FROM_MAILBOX_SORT_REVERSE = new SortField(FIRST_FROM_MAILBOX_NAME_FIELD, SortField.LONG, true);
 
+    
     private final static SortField ARRIVAL_MAILBOX_SORT = new SortField(INTERNAL_DATE_FIELD_MILLISECOND_RESOLUTION, SortField.LONG);
     private final static SortField ARRIVAL_MAILBOX_SORT_REVERSE = new SortField(INTERNAL_DATE_FIELD_MILLISECOND_RESOLUTION, SortField.LONG, true);
 
@@ -262,6 +259,13 @@ public class LuceneMessageSearchIndex<Id
     private final static SortField SENT_DATE_SORT = new SortField(SENT_DATE_FIELD_MILLISECOND_RESOLUTION, SortField.LONG);
     private final static SortField SENT_DATE_SORT_REVERSE = new SortField(SENT_DATE_FIELD_MILLISECOND_RESOLUTION, SortField.LONG, true);
     
+    private final static SortField FIRST_TO_MAILBOX_DISPLAY_SORT = new SortField(FIRST_TO_MAILBOX_DISPLAY_FIELD, SortField.LONG);
+    private final static SortField FIRST_TO_MAILBOX_DISPLAY_SORT_REVERSE = new SortField(FIRST_TO_MAILBOX_DISPLAY_FIELD, SortField.LONG, true);
+
+    private final static SortField FIRST_FROM_MAILBOX_DISPLAY_SORT = new SortField(FIRST_FROM_MAILBOX_DISPLAY_FIELD, SortField.LONG);
+    private final static SortField FIRST_FROM_MAILBOX_DISPLAY_SORT_REVERSE = new SortField(FIRST_FROM_MAILBOX_DISPLAY_FIELD, SortField.LONG, true);
+
+    
     public LuceneMessageSearchIndex(Directory directory) throws CorruptIndexException, LockObtainFailedException, IOException {
         this(directory, true);
     }
@@ -366,11 +370,11 @@ public class LuceneMessageSearchIndex<Id
     private Document createMessageDocument(final Message<?> membership) throws MailboxException{
         final Document doc = new Document();
         // TODO: Better handling
-        doc.add(new Field(MAILBOX_ID_FIELD, membership.getMailboxId().toString().toLowerCase(Locale.US), Store.YES, Index.NOT_ANALYZED));
+        doc.add(new Field(MAILBOX_ID_FIELD, membership.getMailboxId().toString().toUpperCase(Locale.ENGLISH), Store.YES, Index.NOT_ANALYZED));
         doc.add(new NumericField(UID_FIELD,Store.YES, true).setLongValue(membership.getUid()));
         
         // create an unqiue key for the document which can be used later on updates to find the document
-        doc.add(new Field(ID_FIELD, membership.getMailboxId().toString().toLowerCase(Locale.US) +"-" + Long.toString(membership.getUid()), Store.YES, Index.NOT_ANALYZED));
+        doc.add(new Field(ID_FIELD, membership.getMailboxId().toString().toUpperCase(Locale.ENGLISH) +"-" + Long.toString(membership.getUid()), Store.YES, Index.NOT_ANALYZED));
 
         doc.add(new NumericField(INTERNAL_DATE_FIELD_YEAR_RESOLUTION,Store.NO, true).setLongValue(DateUtils.truncate(membership.getInternalDate(),Calendar.YEAR).getTime()));
         doc.add(new NumericField(INTERNAL_DATE_FIELD_MONTH_RESOLUTION,Store.NO, true).setLongValue(DateUtils.truncate(membership.getInternalDate(),Calendar.MONTH).getTime()));
@@ -389,13 +393,18 @@ public class LuceneMessageSearchIndex<Id
             public void headers(Header header) {
                 
                 Date sentDate = null;
+                String firstFromMailbox = "";
+                String firstToMailbox = "";
+                String firstCcMailbox = "";
+                String firstFromDisplay = "";
+                String firstToDisplay = "";
                 
                 Iterator<org.apache.james.mime4j.parser.Field> fields = header.iterator();
                 while(fields.hasNext()) {
                     org.apache.james.mime4j.parser.Field f = fields.next();
-                    String headerName = f.getName().toLowerCase(Locale.US);
-                    String headerValue = f.getBody().toLowerCase(Locale.US);
-                    String fullValue =  f.toString().toLowerCase(Locale.US);
+                    String headerName = f.getName().toUpperCase(Locale.ENGLISH);
+                    String headerValue = f.getBody().toUpperCase(Locale.ENGLISH);
+                    String fullValue =  f.toString().toUpperCase(Locale.ENGLISH);
                     doc.add(new Field(HEADERS_FIELD, fullValue, Store.NO, Index.ANALYZED));
                     doc.add(new Field(PREFIX_HEADER_FIELD + headerName, headerValue, Store.NO, Index.ANALYZED));
                     
@@ -403,19 +412,12 @@ public class LuceneMessageSearchIndex<Id
                     if (f instanceof AddressListField) {
                         AddressListField addressField = (AddressListField) f;
                         String field = null;
-                        String firstField = null;
                         if ("To".equalsIgnoreCase(headerName)) {
                             field = TO_FIELD;
-                            firstField = FIRST_TO_MAILBOX_NAME_FIELD;
                         } else if ("From".equalsIgnoreCase(headerName)) {
                             field = FROM_FIELD;
-                            firstField = FIRST_FROM_MAILBOX_NAME_FIELD;
-
-                        } else if ("Bcc".equalsIgnoreCase(headerName)) {
-                            field = BCC_FIELD;
                         } else if ("Cc".equalsIgnoreCase(headerName)) {
                             field = CC_FIELD;
-                            firstField = FIRST_CC_MAILBOX_NAME_FIELD;
                         }
                         
                         // Check if we can index the the addressfield in the right manner
@@ -427,23 +429,47 @@ public class LuceneMessageSearchIndex<Id
                                     Address address = aList.get(i);
                                     if (address instanceof org.apache.james.mime4j.field.address.Mailbox) {
                                         org.apache.james.mime4j.field.address.Mailbox mailbox = (org.apache.james.mime4j.field.address.Mailbox) address;
-                                        String value = mailbox.getEncodedString().toLowerCase(Locale.US);
-                                        String mailboxName = mailbox.getName();
+                                        String value = mailbox.getEncodedString().toUpperCase(Locale.ENGLISH);
                                         
                                         doc.add(new Field(field, value, Store.NO, Index.ANALYZED));
                                         
-                                        if (i == 0 && firstField != null && mailboxName != null) {
-                                            doc.add(new Field(firstField, mailboxName.toLowerCase(Locale.US), Store.YES, Index.NOT_ANALYZED));
+                                        if (i == 0) {
+                                            String mailboxAddress = SearchUtil.getMailboxAddress(mailbox);
+                                            String mailboxDisplay = SearchUtil.getDisplayAddress(mailbox);
+
+                                            if ("To".equalsIgnoreCase(headerName)) {
+                                                firstToMailbox = mailboxAddress;
+                                                firstToDisplay = mailboxDisplay;
+                                            } else if ("From".equalsIgnoreCase(headerName)) {
+                                                firstFromMailbox = mailboxAddress;
+                                                firstFromDisplay = mailboxDisplay;
+                                                
+                                            } else if ("Cc".equalsIgnoreCase(headerName)) {
+                                                firstCcMailbox = mailboxAddress;
+                                            }
+                                            
                                         }
                                     } else if (address instanceof Group) {
                                         MailboxList mList = ((Group) address).getMailboxes();
                                         for (int a = 0; a < mList.size(); a++) {
-                                            String value = mList.get(a).getEncodedString().toLowerCase(Locale.US);
+                                            org.apache.james.mime4j.field.address.Mailbox mailbox = mList.get(a);
+                                            String value = mailbox.getEncodedString().toUpperCase(Locale.ENGLISH);
                                             doc.add(new Field(field, value, Store.NO, Index.ANALYZED));
-                                            String mailboxName = mList.get(a).getName();
 
-                                            if (i == 0 && a == 0 && firstField != null && mailboxName != null) {
-                                                doc.add(new Field(firstField, mailboxName.toLowerCase(Locale.US), Store.YES, Index.NOT_ANALYZED));
+                                            if (i == 0 && a == 0) {
+                                                String mailboxAddress = SearchUtil.getMailboxAddress(mailbox);
+                                                String mailboxDisplay = SearchUtil.getDisplayAddress(mailbox);
+
+                                                if ("To".equalsIgnoreCase(headerName)) {
+                                                    firstToMailbox = mailboxAddress;
+                                                    firstToDisplay = mailboxDisplay;
+                                                } else if ("From".equalsIgnoreCase(headerName)) {
+                                                    firstFromMailbox = mailboxAddress;
+                                                    firstFromDisplay = mailboxDisplay;
+
+                                                } else if ("Cc".equalsIgnoreCase(headerName)) {
+                                                    firstCcMailbox = mailboxAddress;
+                                                }
                                             }
                                         }
                                     }
@@ -459,9 +485,13 @@ public class LuceneMessageSearchIndex<Id
                 if (sentDate == null) {
                     sentDate = membership.getInternalDate();
                 }
-                doc.add(new NumericField(SENT_DATE_FIELD_MILLISECOND_RESOLUTION,Store.NO, true).setLongValue(DateUtils.truncate(sentDate,Calendar.MILLISECOND).getTime()));
-
+                doc.add(new NumericField(SENT_DATE_FIELD_MILLISECOND_RESOLUTION,Store.YES, true).setLongValue(DateUtils.truncate(sentDate,Calendar.MILLISECOND).getTime()));
 
+                doc.add(new Field(FIRST_FROM_MAILBOX_NAME_FIELD, firstFromMailbox, Store.YES, Index.NOT_ANALYZED));
+                doc.add(new Field(FIRST_TO_MAILBOX_NAME_FIELD, firstToMailbox, Store.YES, Index.NOT_ANALYZED));
+                doc.add(new Field(FIRST_CC_MAILBOX_NAME_FIELD, firstCcMailbox, Store.YES, Index.NOT_ANALYZED));
+                doc.add(new Field(FIRST_FROM_MAILBOX_DISPLAY_FIELD, firstFromDisplay, Store.YES, Index.NOT_ANALYZED));
+                doc.add(new Field(FIRST_TO_MAILBOX_DISPLAY_FIELD, firstToDisplay, Store.YES, Index.NOT_ANALYZED));
            
             }
             /*
@@ -487,7 +517,7 @@ public class LuceneMessageSearchIndex<Id
                     BufferedReader bodyReader = new BufferedReader(new InputStreamReader(in, charset));
                     String line = null;
                     while((line = bodyReader.readLine()) != null) {
-                        doc.add(new Field(BODY_FIELD,  line.toLowerCase(Locale.US),Store.NO, Index.ANALYZED));
+                        doc.add(new Field(BODY_FIELD,  line.toUpperCase(Locale.ENGLISH),Store.NO, Index.ANALYZED));
                     }
                     
                 }
@@ -615,14 +645,14 @@ public class LuceneMessageSearchIndex<Id
      */
     private Query createHeaderQuery(SearchQuery.HeaderCriterion crit) throws UnsupportedSearchException {
         HeaderOperator op = crit.getOperator();
-        String fieldName = PREFIX_HEADER_FIELD + crit.getHeaderName().toLowerCase(Locale.US);
+        String fieldName = PREFIX_HEADER_FIELD + crit.getHeaderName().toUpperCase(Locale.ENGLISH);
         if (op instanceof SearchQuery.ContainsOperator) {
             ContainsOperator cop = (ContainsOperator) op;
-            return createTermQuery(fieldName, cop.getValue().toLowerCase(Locale.US));
+            return createTermQuery(fieldName, cop.getValue().toUpperCase(Locale.ENGLISH));
         } else if (op instanceof SearchQuery.ExistsOperator){
             return new PrefixQuery(new Term(fieldName, ""));
         } else if (op instanceof SearchQuery.AddressOperator) {
-            return createTermQuery(fieldName.toLowerCase(), ((SearchQuery.AddressOperator) op).getAddress().toLowerCase(Locale.US));
+            return createTermQuery(fieldName.toLowerCase(), ((SearchQuery.AddressOperator) op).getAddress().toUpperCase(Locale.ENGLISH));
         } else {
             // Operator not supported
             throw new UnsupportedSearchException();
@@ -757,14 +787,14 @@ public class LuceneMessageSearchIndex<Id
                     sf = SENT_DATE_SORT;
                 }
                 break;
-            case Cc:
+            case MailboxCc:
                 if (reverse) {
                     sf = FIRST_CC_MAILBOX_SORT_REVERSE;
                 } else {
                     sf = FIRST_CC_MAILBOX_SORT;
                 }
                 break;
-            case From:
+            case MailboxFrom:
                 if (reverse) {
                     sf = FIRST_FROM_MAILBOX_SORT_REVERSE;
                 } else {
@@ -778,14 +808,14 @@ public class LuceneMessageSearchIndex<Id
                     sf = SIZE_SORT;
                 }
                 break;
-            case Subject:
+            case BaseSubject:
                 if (reverse) {
                     sf = BASE_SUBJECT_SORT_REVERSE;
                 } else {
                     sf = BASE_SUBJECT_SORT;
                 }
                 break;
-            case To:
+            case MailboxTo:
                 if (reverse) {
                     sf = FIRST_TO_MAILBOX_SORT_REVERSE;
                 } else {
@@ -800,6 +830,20 @@ public class LuceneMessageSearchIndex<Id
                     sf = UID_SORT;
                 }
                 break;
+            case DisplayFrom:
+                if (reverse) {
+                    sf = FIRST_FROM_MAILBOX_DISPLAY_SORT_REVERSE;;
+                } else {
+                    sf = FIRST_FROM_MAILBOX_DISPLAY_SORT;
+                }
+                break;
+            case DisplayTo:
+                if (reverse) {
+                    sf = FIRST_TO_MAILBOX_DISPLAY_SORT_REVERSE;
+                } else {
+                    sf = FIRST_TO_MAILBOX_DISPLAY_SORT;
+                }
+                break;   
             default:
                 break;
             }
@@ -851,7 +895,7 @@ public class LuceneMessageSearchIndex<Id
      * @throws UnsupportedSearchException
      */
     private Query createTextQuery(SearchQuery.TextCriterion crit) throws UnsupportedSearchException {
-        String value = crit.getOperator().getValue().toLowerCase(Locale.US);
+        String value = crit.getOperator().getValue().toUpperCase(Locale.ENGLISH);
         switch(crit.getType()) {
         case BODY:
             return createTermQuery(BODY_FIELD, value);

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/StrictImapSearchAnalyzer.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/StrictImapSearchAnalyzer.java?rev=1133447&r1=1133446&r2=1133447&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/StrictImapSearchAnalyzer.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/StrictImapSearchAnalyzer.java Wed Jun  8 15:53:54 2011
@@ -21,11 +21,9 @@ package org.apache.james.mailbox.store.s
 import java.io.Reader;
 
 import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.LowerCaseFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.cn.smart.SentenceTokenizer;
 import org.apache.lucene.analysis.ngram.NGramTokenFilter;
-import org.apache.lucene.util.Version;
 
 /**
 *
@@ -55,7 +53,7 @@ public final class StrictImapSearchAnaly
     * @see org.apache.lucene.analysis.Analyzer#tokenStream(java.lang.String, java.io.Reader)
     */
    public TokenStream tokenStream(String fieldName, Reader reader) {
-       return new NGramTokenFilter(new LowerCaseFilter(Version.LUCENE_31, new SentenceTokenizer(reader)), minTokenLength, maxTokenLength);
+       return new NGramTokenFilter(new UpperCaseFilter(new SentenceTokenizer(reader)), minTokenLength, maxTokenLength);
    }
    
 }
\ No newline at end of file

Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/UpperCaseFilter.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/UpperCaseFilter.java?rev=1133447&view=auto
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/UpperCaseFilter.java (added)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/search/lucene/UpperCaseFilter.java Wed Jun  8 15:53:54 2011
@@ -0,0 +1,52 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.mailbox.store.search.lucene;
+
+import java.io.IOException;
+
+import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+
+/**
+ * Normalizes token text to upper case.
+ */
+public final class UpperCaseFilter extends TokenFilter {
+    private CharTermAttribute termAtt;
+
+    public UpperCaseFilter(TokenStream in) {
+        super(in);
+        termAtt = addAttribute(CharTermAttribute.class);
+    }
+
+
+    @Override
+    public final boolean incrementToken() throws IOException {
+        if (input.incrementToken()) {
+
+            final char[] buffer = termAtt.buffer();
+            final int length = termAtt.length();
+            for (int i = 0; i < length; i++)
+                buffer[i] = Character.toUpperCase(buffer[i]);
+
+            return true;
+        } else
+            return false;
+    }
+}



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