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 rd...@apache.org on 2007/10/27 12:13:33 UTC
svn commit: r589068 - in /james/server/trunk:
core-library/src/main/java/org/apache/james/mailboxmanager/
core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/
core-library/src/main/java/org/apache/james/mailboxmanager/wrapper/
imap-mailb...
Author: rdonkin
Date: Sat Oct 27 03:13:30 2007
New Revision: 589068
URL: http://svn.apache.org/viewvc?rev=589068&view=rev
Log:
JAMES-806 Search command implementation. Contributed by Zsombor Gegesy (https://issues.apache.org/jira/browse/JAMES-806). Only part of the proposed implementation has been committed.
Added:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java
Modified:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/SearchableMailbox.java
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/wrapper/ImapMailboxSessionWrapper.java
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java
james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java
Added: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java?rev=589068&view=auto
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java (added)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java Sat Oct 27 03:13:30 2007
@@ -0,0 +1,300 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mailboxmanager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class SearchParameters {
+
+ public static final String HEADER = "HEADER";
+ public static final String UID = "UID";
+ public static final String NOT = "NOT";
+ public static final String OR = "OR";
+ public static final String SMALLER = "SMALLER";
+ public static final String LARGER = "LARGER";
+ public static final String SINCE = "SINCE";
+ public static final String SENTSINCE = "SENTSINCE";
+ public static final String SENTON = "SENTON";
+ public static final String SENTBEFORE = "SENTBEFORE";
+ public static final String ON = "ON";
+ public static final String BEFORE = "BEFORE";
+ public static final String UNKEYWORD = "UNKEYWORD";
+ public static final String TO = "TO";
+ public static final String TEXT = "TEXT";
+ public static final String SUBJECT = "SUBJECT";
+ public static final String KEYWORD = "KEYWORD";
+ public static final String FROM = "FROM";
+ public static final String CC = "CC";
+ public static final String BODY = "BODY";
+ public static final String BCC = "BCC";
+ public static final String UNSEEN = "UNSEEN";
+ public static final String UNFLAGGED = "UNFLAGGED";
+ public static final String UNDRAFT = "UNDRAFT";
+ public static final String UNDELETED = "UNDELETED";
+ public static final String UNANSWERED = "UNANSWERED";
+ public static final String SEEN = "SEEN";
+ public static final String RECENT = "RECENT";
+ public static final String OLD = "OLD";
+ public static final String NEW = "NEW";
+ public static final String FLAGGED = "FLAGGED";
+ public static final String DRAFT = "DRAFT";
+ public static final String DELETED = "DELETED";
+ public static final String ANSWERED = "ANSWERED";
+ public static final String ALL = "ALL";
+
+ public final static Set BASE_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ ALL, ANSWERED, DELETED, DRAFT, FLAGGED, NEW, OLD, RECENT, SEEN,
+ UNANSWERED, UNDELETED, UNDRAFT, UNFLAGGED, UNSEEN
+ })));
+
+ public final static Set STRING_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ BCC, BODY, CC, FROM, KEYWORD, SUBJECT, TEXT, TO, UNKEYWORD
+ })));
+ public final static Set DATE_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ BEFORE, ON, SENTBEFORE, SENTON, SENTSINCE , SINCE
+ })));
+ public final static Set NUMBER_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ LARGER, SMALLER
+ })));
+
+ public final static Set SPECIAL_SEARCH_TERMS = new HashSet(Arrays.asList(new String[] {
+ OR, NOT,UID, HEADER
+ }));
+
+
+ List criterias = new ArrayList();
+
+ public void addCriteria(SearchCriteria crit) {
+ criterias.add(crit);
+ }
+
+ public List getCriterias() {
+ return criterias;
+ }
+
+ // @Override
+ public String toString() {
+ return "Search:"+criterias.toString();
+ }
+
+ public static class SearchCriteria {
+
+
+ public String getName() {
+ return "search-criteria";
+ }
+
+ // @Override
+ public String toString() {
+ return "['"+getName()+"']";
+ }
+ }
+
+ public static class NamedSearchCriteria extends SearchCriteria {
+ String name;
+
+ public NamedSearchCriteria(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // @Override
+ public String toString() {
+ return "['"+name+"']";
+ }
+ }
+
+ public static class StringSearchCriteria extends NamedSearchCriteria {
+ String value;
+
+ public StringSearchCriteria(String name, String value) {
+ super(name);
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ public String toString() {
+ return "['"+name+"':'"+value+"']";
+ }
+ }
+
+ public static class NumberSearchCriteria extends NamedSearchCriteria {
+ long value;
+
+ public NumberSearchCriteria(String name, long value) {
+ super(name);
+ this.value = value;
+ }
+
+ public long getValue() {
+ return value;
+ }
+ public String toString() {
+ return "['"+name+"':'"+value+"']";
+ }
+ }
+
+
+
+ public static class DateSearchCriteria extends NamedSearchCriteria {
+ Date value;
+
+ public DateSearchCriteria(String name, Date value) {
+ super(name);
+ this.value = value;
+ }
+
+ public Date getValue() {
+ return value;
+ }
+ public String toString() {
+ return "['"+name+"':'"+value+"']";
+ }
+
+ }
+
+ public static class HeaderSearchCriteria extends SearchCriteria {
+ String fieldName;
+ String value;
+
+ public HeaderSearchCriteria(String fieldName, String value) {
+ this.fieldName = fieldName;
+ this.value = value;
+ }
+ public String getName() {
+ return HEADER;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String toString() {
+ return "[header:'"+fieldName+"':'"+value+"']";
+ }
+
+ }
+
+ public static class UIDSearchCriteria extends SearchCriteria {
+ NumericRange[] idRanges;
+
+ public UIDSearchCriteria(NumericRange[] idRanges) {
+ this.idRanges = idRanges;
+ }
+ public String getName() {
+ return UID;
+ }
+
+ public NumericRange[] getIdRanges() {
+ return idRanges;
+ }
+ }
+
+ public static class NotSearchCriteria extends SearchCriteria {
+ SearchCriteria inverse;
+
+ public NotSearchCriteria(SearchCriteria inverse) {
+ this.inverse = inverse;
+ }
+
+ public String getName() {
+ return NOT;
+ }
+
+ public SearchCriteria getInverse() {
+ return inverse;
+ }
+
+ public String toString() {
+ return "[NOT "+inverse+"]";
+ }
+
+ }
+ public static class OrSearchCriteria extends SearchCriteria {
+ SearchCriteria a,b;
+
+ public OrSearchCriteria (SearchCriteria a, SearchCriteria b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ public String getName() {
+ return OR;
+ }
+
+
+ public SearchCriteria getFirst() {
+ return a;
+ }
+
+ public SearchCriteria getSecond() {
+ return b;
+ }
+ public String toString() {
+ return "[OR "+a+' '+b+"]";
+ }
+
+ }
+
+
+ public static final class NumericRange {
+ private final long lowValue;
+ private final long highValue;
+
+ public NumericRange(final long value) {
+ super();
+ this.lowValue = value;
+ this.highValue = value;
+ }
+
+ public NumericRange(final long lowValue, final long highValue) {
+ super();
+ this.lowValue = lowValue;
+ this.highValue = highValue;
+ }
+
+ public final long getHighValue() {
+ return highValue;
+ }
+
+ public final long getLowValue() {
+ return lowValue;
+ }
+
+ public String toString() {
+ return "[" + lowValue + "->" + highValue + "]";
+ }
+ }
+}
Modified: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/SearchableMailbox.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/SearchableMailbox.java?rev=589068&r1=589067&r2=589068&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/SearchableMailbox.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/SearchableMailbox.java Sat Oct 27 03:13:30 2007
@@ -19,11 +19,10 @@
package org.apache.james.mailboxmanager.mailbox;
-import javax.mail.search.SearchTerm;
-
import org.apache.james.mailboxmanager.GeneralMessageSet;
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
+import org.apache.james.mailboxmanager.SearchParameters;
public interface SearchableMailbox {
/**
@@ -37,5 +36,5 @@
* @throws MailboxManagerException
* if anything went wrong
*/
- MessageResult[] search(GeneralMessageSet set,SearchTerm searchTerm, int result) throws MailboxManagerException;
+ MessageResult[] search(GeneralMessageSet set,SearchParameters searchTerm, int result) throws MailboxManagerException;
}
Modified: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/wrapper/ImapMailboxSessionWrapper.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/wrapper/ImapMailboxSessionWrapper.java?rev=589068&r1=589067&r2=589068&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/wrapper/ImapMailboxSessionWrapper.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/wrapper/ImapMailboxSessionWrapper.java Sat Oct 27 03:13:30 2007
@@ -25,6 +25,7 @@
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
import org.apache.james.mailboxmanager.Quota;
+import org.apache.james.mailboxmanager.SearchParameters;
import org.apache.james.mailboxmanager.acl.MailboxRights;
import org.apache.james.mailboxmanager.impl.MailboxEventDispatcher;
import org.apache.james.mailboxmanager.mailbox.ImapMailbox;
@@ -65,7 +66,7 @@
return ((ImapMailbox) mailbox).getUidNext();
}
- public MessageResult[] search(GeneralMessageSet set, SearchTerm searchTerm, int result) throws MailboxManagerException {
+ public MessageResult[] search(GeneralMessageSet set, SearchParameters searchTerm, int result) throws MailboxManagerException {
return addMsnToResults(((SearchableMailbox)mailbox).search(set, searchTerm, noMsnResult(result)),result);
}
Modified: james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java?rev=589068&r1=589067&r2=589068&view=diff
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java (original)
+++ james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java Sat Oct 27 03:13:30 2007
@@ -39,6 +39,7 @@
import org.apache.james.imapserver.store.MailboxException;
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
+import org.apache.james.mailboxmanager.SearchParameters;
import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
import org.apache.james.mailboxmanager.mailbox.ImapMailboxSession;
@@ -84,8 +85,9 @@
}
MessageResult[] messageResults;
try {
+ // TODO: implementation
messageResults = mailbox.search(GeneralMessageSetImpl.all(),
- searchTerm, resultCode);
+ new SearchParameters(), resultCode);
} catch (MailboxManagerException e) {
throw new MailboxException(e);
}
Modified: james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java?rev=589068&r1=589067&r2=589068&view=diff
==============================================================================
--- james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java (original)
+++ james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java Sat Oct 27 03:13:30 2007
@@ -19,7 +19,10 @@
package org.apache.james.imapserver.commands;
-import javax.mail.Message;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
import javax.mail.search.SearchTerm;
import org.apache.james.imapserver.ImapRequestLineReader;
@@ -29,6 +32,10 @@
import org.apache.james.imapserver.store.MailboxException;
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
+import org.apache.james.mailboxmanager.SearchParameters;
+import org.apache.james.mailboxmanager.SearchParameters.NamedSearchCriteria;
+import org.apache.james.mailboxmanager.SearchParameters.NumericRange;
+import org.apache.james.mailboxmanager.SearchParameters.SearchCriteria;
import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
import org.apache.james.mailboxmanager.mailbox.ImapMailboxSession;
@@ -60,7 +67,7 @@
throws ProtocolException, MailboxException
{
// Parse the search term from the request
- SearchTerm searchTerm = parser.searchTerm( request );
+ SearchParameters searchTerm = parser.searchTerm( request );
parser.endLine( request );
ImapMailboxSession mailbox = session.getSelected().getMailbox();
@@ -106,37 +113,85 @@
return ARGS;
}
+
+
private class SearchCommandParser extends CommandParser
{
/**
* Parses the request argument into a valid search term.
- * Not yet implemented - all searches will return everything for now.
- * TODO implement search
*/
- public SearchTerm searchTerm( ImapRequestLineReader request )
+ public SearchParameters searchTerm( ImapRequestLineReader request )
throws ProtocolException
{
- // Dummy implementation
- // Consume to the end of the line.
- char next = request.nextChar();
- while ( next != '\n' ) {
- request.consume();
+ SearchParameters search = new SearchParameters();
+
+ char next = request.nextChar();
+ while ( next != '\n' && next != '\r') {
+
+ SearchParameters.SearchCriteria crit = parseCriteria(request);
+ search.addCriteria(crit);
next = request.nextChar();
+ while ( next == ' ' ) {
+ request.consume();
+ next = request.nextChar();
+ }
}
- // Return a search term that matches everything.
- return new SearchTerm()
- {
- private static final long serialVersionUID = 5290284637903768771L;
-
- public boolean match( Message message )
- {
- return true;
+ return search;
+ }
+
+ private SearchCriteria parseCriteria(ImapRequestLineReader request) throws ProtocolException {
+ String term = atom(request).toUpperCase();
+
+ if (SearchParameters.BASE_SEARCH_TERMS.contains(term)) {
+ return new SearchParameters.NamedSearchCriteria(term);
+ } else if (SearchParameters.STRING_SEARCH_TERMS.contains(term)) {
+ return new SearchParameters.StringSearchCriteria(term, astring(request));
+ } else if (SearchParameters.NUMBER_SEARCH_TERMS.contains(term)) {
+ return new SearchParameters.NumberSearchCriteria(term, number(request));
+ } else if (SearchParameters.DATE_SEARCH_TERMS.contains(term)) {
+ return new SearchParameters.DateSearchCriteria(term, date(request));
+ } else if ("HEADER".equals(term)) {
+ return new SearchParameters.HeaderSearchCriteria(astring(request), astring(request));
+ } else if ("UID".equals(term)) {
+ return new SearchParameters.UIDSearchCriteria(toNumericRange(parseIdRange(request)));
+ } else if ("OR".equals(term)) {
+ return new SearchParameters.OrSearchCriteria(parseCriteria(request), parseCriteria(request));
+ } else if ("NOT".equals(term)) {
+ return new SearchParameters.NotSearchCriteria(parseCriteria(request));
+ } else {
+ throw new ProtocolException("Term '"+term+"' not supported in the current search implementation!");
+ }
+ }
+
+ private NumericRange[] toNumericRange(final IdRange[] ranges) {
+ final NumericRange[] result;
+ if (ranges == null) {
+ result = null;
+ } else {
+ final int length = ranges.length;
+ result = new NumericRange[length];
+ for (int i=0;i<length; i++) {
+ result[i] = toNumericRange(ranges[i]);
}
- };
+ }
+
+ return result;
+ }
+
+ private NumericRange toNumericRange(IdRange range) {
+ final NumericRange result;
+ if (range == null) {
+ result = null;
+ } else {
+ result = new NumericRange(range.getLowVal(), range.getHighVal());
+ }
+ return result;
}
}
+
+
}
/*
6.4.4. SEARCH Command
Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java
URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java?rev=589068&r1=589067&r2=589068&view=diff
==============================================================================
--- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java (original)
+++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java Sat Oct 27 03:13:30 2007
@@ -30,13 +30,13 @@
import javax.mail.Flags;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
-import javax.mail.search.SearchTerm;
import org.apache.commons.logging.Log;
import org.apache.james.mailboxmanager.GeneralMessageSet;
import org.apache.james.mailboxmanager.MailboxListener;
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
+import org.apache.james.mailboxmanager.SearchParameters;
import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
import org.apache.james.mailboxmanager.impl.MailboxEventDispatcher;
import org.apache.james.mailboxmanager.impl.MessageResultImpl;
@@ -60,6 +60,7 @@
import org.apache.torque.util.Criteria;
import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
+
import com.sun.mail.util.CRLFOutputStream;
import com.workingdogs.village.DataSetException;
@@ -653,7 +654,7 @@
this.mailboxRow = mailboxRow;
}
- public MessageResult[] search(GeneralMessageSet set, SearchTerm searchTerm,
+ public MessageResult[] search(GeneralMessageSet set, SearchParameters parameters,
int result) throws MailboxManagerException {
try {
lock.readLock().acquire();
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org