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