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]>

Reply via email to