darrell 2002/12/03 22:06:45
Modified: proposals/imap2/java/org/apache/james/imapserver
JamesImapHost.java
proposals/imap2/java/org/apache/james/imapserver/commands
CommandParser.java
proposals/imap2/test/org/apache/james/imapserver
CommandParserTest.java Copy.test ImapHostTest.java
Log:
IMAP Proposal updates.
* Fixed JamesImapHost.copyMessage() implementation.
* Handle '*' and ',' in "set" parameters, eg 1:* and 1,3,4
Revision Changes Path
1.5 +19 -7
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/JamesImapHost.java
Index: JamesImapHost.java
===================================================================
RCS file:
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/JamesImapHost.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- JamesImapHost.java 3 Dec 2002 14:00:11 -0000 1.4
+++ JamesImapHost.java 4 Dec 2002 06:06:44 -0000 1.5
@@ -13,19 +13,20 @@
import org.apache.james.imapserver.store.ImapMailbox;
import org.apache.james.imapserver.store.MailboxException;
import org.apache.james.imapserver.store.SimpleImapMessage;
+import org.apache.james.imapserver.store.MessageFlags;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.ConsoleLogger;
-import examples.messages;
-
import javax.mail.search.SearchTerm;
import javax.mail.internet.MimeMessage;
+import javax.mail.MessagingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Map;
import java.util.HashMap;
+import java.util.Date;
/**
* An initial implementation of an ImapHost. By default, uses,
@@ -313,13 +314,24 @@
return matchedUids;
}
+ /** @see {@link ImapHost#copyMessage } */
public void copyMessage( long uid, ImapMailbox currentMailbox, ImapMailbox
toMailbox )
throws MailboxException
{
- SimpleImapMessage message = currentMailbox.getMessage( uid );
- toMailbox.createMessage( message.getMimeMessage(),
- message.getFlags(),
- message.getInternalDate() );
+ SimpleImapMessage originalMessage = currentMailbox.getMessage( uid );
+ MimeMessage newMime = null;
+ try {
+ newMime = new MimeMessage( originalMessage.getMimeMessage() );
+ }
+ catch ( MessagingException e ) {
+ // TODO chain.
+ throw new MailboxException( "Messaging exception: " + e.getMessage() );
+ }
+ MessageFlags newFlags = new MessageFlags();
+ newFlags.setAll( originalMessage.getFlags() );
+ Date newDate = originalMessage.getInternalDate();
+
+ toMailbox.createMessage( newMime, newFlags, newDate);
}
/**
1.5 +60 -8
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CommandParser.java
Index: CommandParser.java
===================================================================
RCS file:
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CommandParser.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CommandParser.java 3 Dec 2002 14:00:11 -0000 1.4
+++ CommandParser.java 4 Dec 2002 06:06:44 -0000 1.5
@@ -15,6 +15,8 @@
import java.util.Date;
import java.util.TimeZone;
+import java.util.List;
+import java.util.ArrayList;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
@@ -404,15 +406,37 @@
CharacterValidator validator = new MessageSetCharValidator();
String nextWord = consumeWord( request, validator );
- int pos = nextWord.indexOf( ':' );
+ int commaPos = nextWord.indexOf( ',' );
+ if ( commaPos == -1 ) {
+ return singleRangeSet( nextWord );
+ }
+
+ CompoundIdSet compoundSet = new CompoundIdSet();
+ int pos = 0;
+ while ( commaPos != -1 ) {
+ String range = nextWord.substring( pos, commaPos );
+ IdSet set = singleRangeSet( range );
+ compoundSet.addIdSet( set );
+
+ pos = commaPos + 1;
+ commaPos = nextWord.indexOf( ',', pos );
+ }
+ String range = nextWord.substring( pos );
+ compoundSet.addIdSet( singleRangeSet( range ) );
+ return compoundSet;
+ }
+
+ private IdSet singleRangeSet( String range ) throws ProtocolException
+ {
+ int pos = range.indexOf( ':' );
try {
if ( pos == -1 ) {
- long value = Long.parseLong( nextWord );
+ long value = parseLong( range );
return new HighLowIdSet( value, value );
}
else {
- long lowVal = Long.parseLong( nextWord.substring(0, pos ) );
- long highVal = Long.parseLong( nextWord.substring( pos + 1 ) );
+ long lowVal = parseLong( range.substring(0, pos ) );
+ long highVal = parseLong( range.substring( pos + 1 ) );
return new HighLowIdSet( lowVal, highVal );
}
}
@@ -421,6 +445,12 @@
}
}
+ private long parseLong( String value ) {
+ if ( value.length() == 1 && value.charAt(0) == '*' ) {
+ return Long.MAX_VALUE;
+ }
+ return Long.parseLong( value );
+ }
/**
* Provides the ability to ensure characters are part of a permitted set.
*/
@@ -464,7 +494,8 @@
{
public boolean isValid( char chr )
{
- return ( chr >= '0' && chr <= '9' );
+ return ( ( chr >= '0' && chr <= '9' ) ||
+ chr == '*' );
}
}
@@ -481,9 +512,10 @@
{
public boolean isValid( char chr )
{
- return isDigit( chr ) ||
+ return ( isDigit( chr ) ||
chr == ':' ||
- chr == ',';
+ chr == '*' ||
+ chr == ',' );
}
private boolean isDigit( char chr )
@@ -505,6 +537,26 @@
public boolean includes( long value ) {
return ( lowVal <= value ) && ( value <= highVal );
+ }
+ }
+
+ private class CompoundIdSet implements IdSet
+ {
+ private List idSets = new ArrayList();
+
+ void addIdSet( IdSet set ) {
+ idSets.add( set );
+ }
+
+ public boolean includes( long value )
+ {
+ for ( int i = 0; i < idSets.size(); i++ ) {
+ IdSet idSet = ( IdSet ) idSets.get( i );
+ if ( idSet.includes( value ) ) {
+ return true;
+ }
+ }
+ return false;
}
}
1.5 +41 -1
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/CommandParserTest.java
Index: CommandParserTest.java
===================================================================
RCS file:
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/CommandParserTest.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CommandParserTest.java 3 Dec 2002 14:00:13 -0000 1.4
+++ CommandParserTest.java 4 Dec 2002 06:06:45 -0000 1.5
@@ -8,6 +8,7 @@
package org.apache.james.imapserver;
import org.apache.james.imapserver.commands.CommandParser;
+import org.apache.james.imapserver.commands.IdSet;
import junit.framework.TestCase;
@@ -167,6 +168,45 @@
formatter.setTimeZone( TimeZone.getTimeZone( "UTC" ));
String actual = formatter.format( parser.dateTime( request ) );
assertEquals( "19710320 00:23:02", actual );
+ }
+
+ /**
+ * Tests parsing of "set" arguments.
+ */
+ public void testIdSet() throws Exception
+ {
+ String testRequest = "8 25 1:4 33:* 2,3,4 1,4:6,8:* ";
+ ImapRequestLineReader request = getRequest( testRequest );
+
+ IdSet idSet;
+ idSet = parser.set( request );
+ checkSet( idSet, new long[]{8}, new long[]{0, 2, 7, 9, 20, Long.MAX_VALUE }
);
+
+ idSet = parser.set( request );
+ checkSet( idSet, new long[]{ 25 }, new long[]{ 0, 5, 20, 30, Long.MAX_VALUE
} );
+
+ idSet = parser.set( request );
+ checkSet( idSet, new long[]{ 1, 2, 3, 4 }, new long[]{0, 5, 10 } );
+
+ idSet = parser.set( request );
+ checkSet( idSet, new long[]{ 33, 35, 100, 1000, Long.MAX_VALUE}, new
long[]{0, 1, 32});
+
+ idSet = parser.set( request );
+ checkSet( idSet, new long[]{ 2,3,4}, new long[]{0, 1, 5,8 });
+
+ idSet = parser.set( request );
+ checkSet( idSet, new long[]{ 1,4,5,6,8,100,1000,Long.MAX_VALUE}, new
long[]{0,2,3,7});
+
+ }
+
+ private void checkSet( IdSet idSet, long[] includes, long[] excludes )
+ {
+ for ( int i = 0; i < includes.length; i++ ) {
+ assertTrue( idSet.includes( includes[i] ));
+ }
+ for ( int i = 0; i < excludes.length; i++ ) {
+ assertTrue( ! idSet.includes( excludes[i] ));
+ }
}
/**
1.2 +8 -0
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Copy.test
Index: Copy.test
===================================================================
RCS file:
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Copy.test,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Copy.test 3 Dec 2002 14:00:13 -0000 1.1
+++ Copy.test 4 Dec 2002 06:06:45 -0000 1.2
@@ -5,16 +5,24 @@
S: \* STATUS copied \(MESSAGES 0\)
S: a1 OK STATUS completed
+# mark one message as deleted before copying (to check that flags are copied)
C: a1 STORE 3 FLAGS (\Deleted)
S: \* 3 FETCH \(FLAGS \(\\Deleted\)
S: a1 OK STORE completed
+# copy messages 2-4
C: a1 COPY 2:4 copied
S: a1 OK COPY completed
+# Check there's 3 messages in the copied mailbox
C: a1 STATUS copied (MESSAGES)
S: \* STATUS copied \(MESSAGES 3\)
S: a1 OK STATUS completed
+
+# Modify an original after copying, to ensure it's not the same message.
+C: a1 STORE 2 FLAGS (\Flagged)
+S: \* 2 FETCH \(FLAGS \(\\Flagged\)
+S: a1 OK STORE completed
C: a1 SELECT copied
S: \* FLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\Seen\)
1.4 +3 -1
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/ImapHostTest.java
Index: ImapHostTest.java
===================================================================
RCS file:
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/ImapHostTest.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ImapHostTest.java 27 Nov 2002 01:59:22 -0000 1.3
+++ ImapHostTest.java 4 Dec 2002 06:06:45 -0000 1.4
@@ -25,6 +25,8 @@
* - Rename
* - Rename Inbox
* - ListMailboxes
+ * - Copying messages - need to make sure that the copied message
+ * is independent of the original
*
* @author Darrell DeBoer <[EMAIL PROTECTED]>
*
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>