james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From darr...@apache.org
Subject cvs commit: james-server/proposals/imap2/test/org/apache/james/imapserver CommandParserTest.java ImapMailboxTest.java Store.test
Date Mon, 21 Jul 2003 23:31:07 GMT
darrell     2003/07/21 16:31:07

  Modified:    proposals/imap2/java/org/apache/james/imapserver
                        ImapSession.java ImapSessionImpl.java
                        ImapSessionMailbox.java JamesImapHost.java
               proposals/imap2/java/org/apache/james/imapserver/commands
                        AppendCommand.java CapabilityCommand.java
                        CheckCommand.java CommandParser.java
                        CopyCommand.java ExpungeCommand.java
                        FetchCommand.java NoopCommand.java
                        SearchCommand.java SelectCommand.java
                        SelectedStateCommand.java StoreCommand.java
               proposals/imap2/java/org/apache/james/imapserver/store
                        ImapMailbox.java InMemoryStore.java
                        MailboxListener.java SimpleImapMessage.java
               proposals/imap2/test/org/apache/james/imapserver
                        CommandParserTest.java ImapMailboxTest.java
                        Store.test
  Added:       proposals/imap2 .cvsignore
               proposals/imap2/java/org/apache/james/imapserver/commands
                        IdRange.java MsnRange.java
  Log:
  Imap2 proposal
  - More tests for ImapMailbox
  - other refactorings
  
  Revision  Changes    Path
  1.1                  james-server/proposals/imap2/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  dist
  build
  velocity.log
  
  
  
  1.7       +5 -2      james-server/proposals/imap2/java/org/apache/james/imapserver/ImapSession.java
  
  Index: ImapSession.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/ImapSession.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ImapSession.java	13 Jul 2003 06:04:56 -0000	1.6
  +++ ImapSession.java	21 Jul 2003 23:31:03 -0000	1.7
  @@ -62,6 +62,7 @@
   import org.apache.mailet.User;
   import org.apache.mailet.UsersRepository;
   import org.apache.james.imapserver.store.ImapMailbox;
  +import org.apache.james.imapserver.store.MailboxException;
   
   /**
    * Encapsulates all state held for an ongoing Imap session,
  @@ -79,7 +80,7 @@
        * responses when the selected mailbox is modified by another user.
        * @param response The response to write to
        */
  -    public void unsolicitedResponses( ImapResponse response );
  +    public void unsolicitedResponses( ImapResponse response ) throws MailboxException;
   
       /**
        * Closes the connection for this session.
  @@ -151,5 +152,7 @@
        * @return the currently selected mailbox.
        */
       ImapSessionMailbox getSelected();
  +
  +    void unsolicitedResponses( ImapResponse request, boolean omitExpunged ) throws MailboxException;
   
   }
  
  
  
  1.6       +34 -12    james-server/proposals/imap2/java/org/apache/james/imapserver/ImapSessionImpl.java
  
  Index: ImapSessionImpl.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/ImapSessionImpl.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ImapSessionImpl.java	13 Jul 2003 06:04:56 -0000	1.5
  +++ ImapSessionImpl.java	21 Jul 2003 23:31:04 -0000	1.6
  @@ -59,9 +59,15 @@
   package org.apache.james.imapserver;
   
   import org.apache.james.imapserver.store.ImapMailbox;
  +import org.apache.james.imapserver.store.MailboxException;
  +import org.apache.james.imapserver.store.MessageFlags;
   import org.apache.mailet.User;
   import org.apache.mailet.UsersRepository;
   
  +import javax.mail.Flags;
  +import java.util.Map;
  +import java.util.Iterator;
  +
   /**
    *
    * @author  Darrell DeBoer <darrell@apache.org>
  @@ -100,23 +106,39 @@
           return imapHost;
       }
   
  -    public void unsolicitedResponses( ImapResponse request )
  -    {
  +    public void unsolicitedResponses( ImapResponse request ) throws MailboxException {
  +        unsolicitedResponses(request, false);
  +    }
  +
  +    public void unsolicitedResponses( ImapResponse request, boolean omitExpunged ) throws MailboxException {
           ImapSessionMailbox selected = getSelected();
           if (selected != null) {
  -            
  -            // Expunge response
  -            int[] expunged = selected.getExpunged();
  -            for (int i = 0; i < expunged.length; i++) {
  -                int msn = expunged[i];
  -                request.expungeResponse(msn);
  -            }
  -            
  -            // New message response 
  +            // New message response
               // TODO: need RECENT...
               if (selected._sizeChanged) {
                   request.existsResponse(selected.getMessageCount());
                   selected._sizeChanged = false;
  +            }
  +
  +            Map flagUpdates = selected.getFlagUpdates();
  +            Iterator iter = flagUpdates.entrySet().iterator();
  +            while (iter.hasNext()) {
  +                Map.Entry entry = (Map.Entry) iter.next();
  +                int msn = ((Integer) entry.getKey()).intValue();
  +                Flags updatedFlags = (Flags) entry.getValue();
  +                StringBuffer out = new StringBuffer( "FLAGS " );
  +                out.append( MessageFlags.format(updatedFlags) );
  +                request.fetchResponse(msn, out.toString());
  +
  +            }
  +
  +            if (! omitExpunged) {
  +                // Expunge response - TODO can't send on certain commands
  +                int[] expunged = selected.getExpunged();
  +                for (int i = 0; i < expunged.length; i++) {
  +                    int msn = expunged[i];
  +                    request.expungeResponse(msn);
  +                }
               }
           }
       }
  
  
  
  1.3       +51 -27    james-server/proposals/imap2/java/org/apache/james/imapserver/ImapSessionMailbox.java
  
  Index: ImapSessionMailbox.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/ImapSessionMailbox.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ImapSessionMailbox.java	13 Jul 2003 12:04:29 -0000	1.2
  +++ ImapSessionMailbox.java	21 Jul 2003 23:31:04 -0000	1.3
  @@ -57,20 +57,17 @@
    */
   package org.apache.james.imapserver;
   
  +import org.apache.james.core.MailImpl;
  +import org.apache.james.imapserver.commands.IdRange;
   import org.apache.james.imapserver.store.ImapMailbox;
  -import org.apache.james.imapserver.store.MailboxListener;
   import org.apache.james.imapserver.store.MailboxException;
  -import org.apache.james.imapserver.store.MessageFlags;
  +import org.apache.james.imapserver.store.MailboxListener;
   import org.apache.james.imapserver.store.SimpleImapMessage;
  -import org.apache.james.core.MailImpl;
   
  -import javax.mail.search.SearchTerm;
  -import javax.mail.internet.MimeMessage;
   import javax.mail.Flags;
  -import java.util.List;
  -import java.util.Collections;
  -import java.util.LinkedList;
  -import java.util.Date;
  +import javax.mail.internet.MimeMessage;
  +import javax.mail.search.SearchTerm;
  +import java.util.*;
   
   public class ImapSessionMailbox implements ImapMailbox, MailboxListener {
       private ImapMailbox _mailbox;
  @@ -78,6 +75,7 @@
       // TODO encapsulate
       public boolean _sizeChanged;
       private List _expungedMsns = Collections.synchronizedList(new LinkedList());
  +    private Map _modifiedFlags = Collections.synchronizedMap(new TreeMap());
   
       public ImapSessionMailbox(ImapMailbox mailbox, boolean readonly) {
           _mailbox = mailbox;
  @@ -107,18 +105,34 @@
           return _readonly;
       }
   
  -    public int[] getExpunged() {
  +    public int[] getExpunged() throws MailboxException {
           synchronized (_expungedMsns) {
               int[] expungedMsns = new int[_expungedMsns.size()];
               for (int i = 0; i < expungedMsns.length; i++) {
  -                Integer msn = (Integer) _expungedMsns.get(i);
  -                expungedMsns[i] = msn.intValue();
  +                int msn = ((Integer) _expungedMsns.get(i)).intValue();
  +                expungedMsns[i] = msn;
               }
               _expungedMsns.clear();
  +
  +            // TODO - renumber any cached ids (for now we assume the _modifiedFlags has been cleared)\
  +            if (! (_modifiedFlags.isEmpty() && ! _sizeChanged ) ) {
  +                throw new IllegalStateException("Need to do this properly...");
  +            }
               return expungedMsns;
           }
       }
   
  +    public Map getFlagUpdates() throws MailboxException {
  +        if (_modifiedFlags.isEmpty()) {
  +            return Collections.EMPTY_MAP;
  +        }
  +
  +        TreeMap retVal = new TreeMap();
  +        retVal.putAll(_modifiedFlags);
  +        _modifiedFlags.clear();
  +        return retVal;
  +    }
  +
       public void expunged(long uid) throws MailboxException {
           synchronized (_expungedMsns) {
               int msn = getMsn(uid);
  @@ -130,6 +144,12 @@
           _sizeChanged = true;
       }
   
  +    public void flagsUpdated(long uid, Flags flags) throws MailboxException {
  +        // This will overwrite any earlier changes
  +        int msn = getMsn(uid);
  +        _modifiedFlags.put(new Integer(msn), flags);
  +    }
  +
       public String getName() {
           return _mailbox.getName();
       }
  @@ -138,10 +158,6 @@
           return _mailbox.getFullName();
       }
   
  -    public Flags getAllowedFlags() {
  -        return _mailbox.getAllowedFlags();
  -    }
  -
       public Flags getPermanentFlags() {
           return _mailbox.getPermanentFlags();
       }
  @@ -158,7 +174,7 @@
           return _mailbox.getUidValidity();
       }
   
  -    public long getFirstUnseen() {
  +    public int getFirstUnseen() {
           return _mailbox.getFirstUnseen();
       }
   
  @@ -174,12 +190,8 @@
           return _mailbox.getUnseenCount();
       }
   
  -    public SimpleImapMessage createMessage( MimeMessage message, Flags flags, Date internalDate ) {
  -        return _mailbox.createMessage(message, flags, internalDate);
  -    }
  -
  -    public void updateMessage( SimpleImapMessage message ) throws MailboxException {
  -        _mailbox.updateMessage(message);
  +    public long appendMessage( MimeMessage message, Flags flags, Date internalDate ) {
  +        return _mailbox.appendMessage(message, flags, internalDate);
       }
   
       public void store( MailImpl mail) throws Exception {
  @@ -194,10 +206,6 @@
           return _mailbox.getMessageUids();
       }
   
  -    public void deleteMessage( long uid ) {
  -        _mailbox.deleteMessage(uid);
  -    }
  -
       public void expunge() throws MailboxException {
           _mailbox.expunge();
       }
  @@ -216,6 +224,22 @@
   
       public void removeListener(MailboxListener listener) {
           _mailbox.removeListener(listener);
  +    }
  +
  +    public IdRange[] msnsToUids(IdRange[] idSet) {
  +        return new IdRange[0];  //To change body of created methods use Options | File Templates.
  +    }
  +
  +    public void setFlags(Flags flags, boolean value, long uid, boolean silent) throws MailboxException {
  +        _mailbox.setFlags(flags, value, uid, silent);
  +    }
  +
  +    public void replaceFlags(Flags flags, long uid, boolean silent) throws MailboxException {
  +        _mailbox.replaceFlags(flags, uid, silent);
  +    }
  +
  +    public void deleteAllMessages() {
  +        _mailbox.deleteAllMessages();
       }
   
   }
  
  
  
  1.10      +3 -7      james-server/proposals/imap2/java/org/apache/james/imapserver/JamesImapHost.java
  
  Index: JamesImapHost.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/JamesImapHost.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- JamesImapHost.java	13 Jul 2003 06:04:56 -0000	1.9
  +++ JamesImapHost.java	21 Jul 2003 23:31:04 -0000	1.10
  @@ -197,17 +197,13 @@
           ImapMailbox toDelete = getMailbox( user, mailboxName, true );
   
           if ( store.getChildren( toDelete ).isEmpty() ) {
  -            long[] uids = toDelete.getMessageUids();
  -            for ( int i = 0; i < uids.length; i++ ) {
  -                long uid = uids[i];
  -                SimpleImapMessage imapMessage = toDelete.getMessage( uid );
  -                toDelete.deleteMessage( imapMessage.getUid() );
  -            }
  +            toDelete.deleteAllMessages();
               store.deleteMailbox( toDelete );
           }
           else {
               if ( toDelete.isSelectable() ) {
                   // TODO delete all messages.
  +                toDelete.deleteAllMessages();
                   store.setSelectable( toDelete, false );
               }
               else {
  
  
  
  1.6       +2 -2      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/AppendCommand.java
  
  Index: AppendCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/AppendCommand.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AppendCommand.java	13 Jul 2003 12:04:29 -0000	1.5
  +++ AppendCommand.java	21 Jul 2003 23:31:04 -0000	1.6
  @@ -116,7 +116,7 @@
               throw e;
           }
   
  -        mailbox.createMessage( message, flags, datetime );
  +        mailbox.appendMessage( message, flags, datetime );
   
           session.unsolicitedResponses( response );
           response.commandComplete( this );
  
  
  
  1.6       +3 -2      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CapabilityCommand.java
  
  Index: CapabilityCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CapabilityCommand.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- CapabilityCommand.java	8 Mar 2003 21:13:55 -0000	1.5
  +++ CapabilityCommand.java	21 Jul 2003 23:31:04 -0000	1.6
  @@ -62,6 +62,7 @@
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  +import org.apache.james.imapserver.store.MailboxException;
   
   /**
    * Handles processeing for the CAPABILITY imap command.
  @@ -81,7 +82,7 @@
       protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
  -            throws ProtocolException
  +            throws ProtocolException, MailboxException
       {
           parser.endLine( request );
           response.untaggedResponse( CAPABILITY_RESPONSE );
  
  
  
  1.4       +3 -2      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CheckCommand.java
  
  Index: CheckCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CheckCommand.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CheckCommand.java	8 Mar 2003 21:13:55 -0000	1.3
  +++ CheckCommand.java	21 Jul 2003 23:31:04 -0000	1.4
  @@ -62,6 +62,7 @@
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  +import org.apache.james.imapserver.store.MailboxException;
   
   /**
    * Handles processeing for the CHECK imap command.
  @@ -78,7 +79,7 @@
       /** @see CommandTemplate#doProcess */
       protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
  -                              ImapSession session ) throws ProtocolException
  +                              ImapSession session ) throws ProtocolException, MailboxException
       {
           parser.endLine( request );
           session.unsolicitedResponses( response );
  
  
  
  1.9       +11 -48    james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CommandParser.java
  
  Index: CommandParser.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CommandParser.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- CommandParser.java	13 Jul 2003 12:04:29 -0000	1.8
  +++ CommandParser.java	21 Jul 2003 23:31:04 -0000	1.9
  @@ -452,7 +452,7 @@
        * Reads a "message set" argument, and parses into an IdSet.
        * Currently only supports a single range of values.
        */
  -    public IdSet set( ImapRequestLineReader request )
  +    public IdRange[] parseIdRange( ImapRequestLineReader request )
               throws ProtocolException
       {
           CharacterValidator validator = new MessageSetCharValidator();
  @@ -460,36 +460,36 @@
   
           int commaPos = nextWord.indexOf( ',' );
           if ( commaPos == -1 ) {
  -            return singleRangeSet( nextWord );
  +            return new IdRange[]{ parseRange( nextWord ) };
           }
   
  -        CompoundIdSet compoundSet = new CompoundIdSet();
  +        ArrayList rangeList = new ArrayList();
           int pos = 0;
           while ( commaPos != -1 ) {
               String range = nextWord.substring( pos, commaPos );
  -            IdSet set = singleRangeSet( range );
  -            compoundSet.addIdSet( set );
  +            IdRange set = parseRange( range );
  +            rangeList.add( set );
   
               pos = commaPos + 1;
               commaPos = nextWord.indexOf( ',', pos );
           }
           String range = nextWord.substring( pos );
  -        compoundSet.addIdSet( singleRangeSet( range ) );
  -        return compoundSet;
  +        rangeList.add( parseRange( range ) );
  +        return (IdRange[]) rangeList.toArray(new IdRange[rangeList.size()]);
       }
   
  -    private IdSet singleRangeSet( String range ) throws ProtocolException
  +    private IdRange parseRange( String range ) throws ProtocolException
       {
           int pos = range.indexOf( ':' );
           try {
               if ( pos == -1 ) {
                   long value = parseLong( range );
  -                return new HighLowIdSet( value, value );
  +                return new IdRange( value );
               }
               else {
                   long lowVal = parseLong( range.substring(0, pos ) );
                   long highVal = parseLong( range.substring( pos + 1 ) );
  -                return new HighLowIdSet( lowVal, highVal );
  +                return new IdRange( lowVal, highVal );
               }
           }
           catch ( NumberFormatException e ) {
  @@ -575,42 +575,5 @@
               return '0' <= chr && chr <= '9';
           }
       }
  -
  -    private class HighLowIdSet implements IdSet
  -    {
  -        private long lowVal;
  -        private long highVal;
  -
  -        public HighLowIdSet( long lowVal, long highVal )
  -        {
  -            this.lowVal = lowVal;
  -            this.highVal = highVal;
  -        }
  -
  -        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       +8 -4      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CopyCommand.java
  
  Index: CopyCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/CopyCommand.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- CopyCommand.java	13 Jul 2003 06:04:56 -0000	1.4
  +++ CopyCommand.java	21 Jul 2003 23:31:04 -0000	1.5
  @@ -94,7 +94,7 @@
                                 boolean useUids)
               throws ProtocolException, MailboxException
       {
  -        IdSet idSet = parser.set( request );
  +        IdRange[] idSet = parser.parseIdRange( request );
           String mailboxName = parser.mailbox( request );
           parser.endLine( request );
   
  @@ -108,16 +108,20 @@
               throw e;
           }
   
  +//        if (! useUids) {
  +//            idSet = currentMailbox.toUidSet(idSet);
  +//        }
  +//        currentMailbox.copyMessages(toMailbox, idSet);
           long[] uids = currentMailbox.getMessageUids();
           for ( int i = 0; i < uids.length; i++ ) {
               long uid = uids[i];
               boolean inSet;
               if ( useUids ) {
  -                inSet = idSet.includes( uid );
  +                inSet = includes( idSet, uid );
               }
               else {
                   int msn = currentMailbox.getMsn( uid );
  -                inSet = idSet.includes( msn );
  +                inSet = includes( idSet, msn );
               }
   
               if ( inSet ) {
  
  
  
  1.5       +2 -1      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/ExpungeCommand.java
  
  Index: ExpungeCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/ExpungeCommand.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ExpungeCommand.java	13 Jul 2003 06:04:56 -0000	1.4
  +++ ExpungeCommand.java	21 Jul 2003 23:31:04 -0000	1.5
  @@ -92,6 +92,7 @@
   
           ImapMailbox mailbox = session.getSelected();
           mailbox.expunge();
  +        System.out.println("here");
   
           session.unsolicitedResponses( response );
           response.commandComplete( this );
  
  
  
  1.6       +7 -7      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/FetchCommand.java
  
  Index: FetchCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/FetchCommand.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FetchCommand.java	13 Jul 2003 12:04:29 -0000	1.5
  +++ FetchCommand.java	21 Jul 2003 23:31:04 -0000	1.6
  @@ -108,7 +108,7 @@
                                 boolean useUids )
               throws ProtocolException, MailboxException
       {
  -        IdSet idSet = parser.set( request );
  +        IdRange[] idSet = parser.parseIdRange( request );
           FetchRequest fetch = parser.fetchRequest( request );
           parser.endLine( request );
   
  @@ -118,20 +118,20 @@
               long uid = uids[i];
               int msn = mailbox.getMsn( uid );
   
  -            if ( ( useUids && idSet.includes( uid ) ) ||
  -                 ( !useUids && idSet.includes( msn ) ) )
  +            if ( ( useUids && includes( idSet, uid ) ) ||
  +                 ( !useUids && includes( idSet, msn ) ) )
               {
                   SimpleImapMessage imapMessage = mailbox.getMessage( uid );
                   String msgData = outputMessage( fetch, imapMessage );
                   response.fetchResponse( msn, msgData );
                   if (imapMessage.getFlags().contains(Flags.Flag.RECENT)) {
  -                    imapMessage.getFlags().remove(Flags.Flag.RECENT);
  -                    mailbox.updateMessage(imapMessage);
  +                    mailbox.setFlags(new Flags(Flags.Flag.RECENT), false, uid, true);
                   }
               }
           }
   
  -        session.unsolicitedResponses( response );
  +        boolean omitExpunged = (!useUids);
  +        session.unsolicitedResponses( response, omitExpunged );
           response.commandComplete( this );
       }
   
  
  
  
  1.5       +3 -2      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/NoopCommand.java
  
  Index: NoopCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/NoopCommand.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- NoopCommand.java	8 Mar 2003 21:13:55 -0000	1.4
  +++ NoopCommand.java	21 Jul 2003 23:31:05 -0000	1.5
  @@ -62,6 +62,7 @@
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  +import org.apache.james.imapserver.store.MailboxException;
   
   /**
    * Handles processeing for the NOOP imap command.
  @@ -78,7 +79,7 @@
       /** @see org.apache.james.imapserver.commands.CommandTemplate#doProcess */
       protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
  -                              ImapSession session ) throws ProtocolException
  +                              ImapSession session ) throws ProtocolException, MailboxException
       {
           parser.endLine( request );
           session.unsolicitedResponses( response );
  
  
  
  1.5       +3 -2      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/SearchCommand.java
  
  Index: SearchCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/SearchCommand.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SearchCommand.java	13 Jul 2003 06:04:56 -0000	1.4
  +++ SearchCommand.java	21 Jul 2003 23:31:05 -0000	1.5
  @@ -120,7 +120,8 @@
   
           response.commandResponse( this, idList.toString() );
   
  -        session.unsolicitedResponses( response );
  +        boolean omitExpunged = (!useUids);
  +        session.unsolicitedResponses( response, omitExpunged );
           response.commandComplete( this );
       }
   
  
  
  
  1.8       +4 -4      james-server/proposals/imap2/java/org/apache/james/imapserver/commands/SelectCommand.java
  
  Index: SelectCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/SelectCommand.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- SelectCommand.java	13 Jul 2003 06:04:56 -0000	1.7
  +++ SelectCommand.java	21 Jul 2003 23:31:05 -0000	1.8
  @@ -92,12 +92,12 @@
           selectMailbox(mailboxName, session);
   
           ImapSessionMailbox mailbox = session.getSelected();
  -        response.flagsResponse( mailbox.getAllowedFlags() );
  +        response.flagsResponse( mailbox.getPermanentFlags() );
           response.existsResponse( mailbox.getMessageCount() );
           response.recentResponse( mailbox.getRecentCount() );
           response.okResponse( "UIDVALIDITY " + mailbox.getUidValidity(), null );
   
  -        long firstUnseen = mailbox.getFirstUnseen();
  +        int firstUnseen = mailbox.getFirstUnseen();
           if ( firstUnseen > 0 ) {
               int msnUnseen = mailbox.getMsn( firstUnseen );
               response.okResponse( "UNSEEN " + msnUnseen,
  @@ -107,7 +107,7 @@
               response.okResponse( null, "No messages unseen" );
           }
           
  -        response.permanentFlagsResponse(mailbox.getAllowedFlags());
  +        response.permanentFlagsResponse(mailbox.getPermanentFlags());
   
           if ( mailbox.isReadonly() ) {
               response.commandComplete( this, "READ-ONLY" );
  
  
  
  1.4       +11 -1     james-server/proposals/imap2/java/org/apache/james/imapserver/commands/SelectedStateCommand.java
  
  Index: SelectedStateCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/SelectedStateCommand.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SelectedStateCommand.java	8 Mar 2003 21:13:55 -0000	1.3
  +++ SelectedStateCommand.java	21 Jul 2003 23:31:05 -0000	1.4
  @@ -77,4 +77,14 @@
       {
           return ( state == ImapSessionState.SELECTED );
       }
  +
  +    protected boolean includes(IdRange[] idSet, long id) {
  +        for (int i = 0; i < idSet.length; i++) {
  +            IdRange idRange = idSet[i];
  +            if (idRange.includes(id)) {
  +                return true;
  +            }
  +        }
  +        return false;
  +    }
   }
  
  
  
  1.5       +42 -18    james-server/proposals/imap2/java/org/apache/james/imapserver/commands/StoreCommand.java
  
  Index: StoreCommand.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/commands/StoreCommand.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StoreCommand.java	13 Jul 2003 12:04:29 -0000	1.4
  +++ StoreCommand.java	21 Jul 2003 23:31:05 -0000	1.5
  @@ -58,10 +58,7 @@
   
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestLineReader;
  -import org.apache.james.imapserver.ImapResponse;
  -import org.apache.james.imapserver.ImapSession;
  -import org.apache.james.imapserver.ProtocolException;
  +import org.apache.james.imapserver.*;
   import org.apache.james.imapserver.store.MessageFlags;
   import org.apache.james.imapserver.store.ImapMailbox;
   import org.apache.james.imapserver.store.SimpleImapMessage;
  @@ -98,33 +95,60 @@
                                 boolean useUids )
               throws ProtocolException, MailboxException
       {
  -        IdSet idSet = parser.set( request );
  +        IdRange[] idSet = parser.parseIdRange( request );
           StoreDirective directive = parser.storeDirective( request );
           Flags flags = parser.flagList( request );
           parser.endLine( request );
   
  -        ImapMailbox mailbox = session.getSelected();
  +        ImapSessionMailbox mailbox = session.getSelected();
  +//        IdRange[] uidSet;
  +//        if (useUids) {
  +//           uidSet = idSet;
  +//        } else {
  +//            uidSet = mailbox.msnsToUids(idSet);
  +//        }
  +//        if (directive.getSign() < 0) {
  +//            mailbox.setFlags(flags, false, uidSet, directive.isSilent());
  +//        }
  +//        else if (directive.getSign() > 0) {
  +//            mailbox.setFlags(flags, true, uidSet, directive.isSilent());
  +//        }
  +//        else {
  +//            mailbox.replaceFlags(flags, uidSet, directive.isSilent());
  +//        }
  +
  +        // TODO do this in one hit.
           long[] uids = mailbox.getMessageUids();
           for ( int i = 0; i < uids.length; i++ ) {
               long uid = uids[i];
               int msn = mailbox.getMsn( uid );
   
  -            if ( ( useUids && idSet.includes( uid ) ) ||
  -                 ( !useUids && idSet.includes( msn ) ) )
  +            if ( ( useUids && includes(idSet, uid) ) ||
  +                 ( !useUids && includes( idSet, msn ) ) )
               {
  -                SimpleImapMessage imapMessage = mailbox.getMessage( uid );
  -                storeFlags( imapMessage, directive, flags );
  -                mailbox.updateMessage( imapMessage );
  -
  -                if ( ! directive.isSilent() ) {
  -                    StringBuffer out = new StringBuffer( "FLAGS " );
  -                    out.append( MessageFlags.format(imapMessage.getFlags()) );
  -                    response.fetchResponse( msn, out.toString() );
  +                if (directive.getSign() < 0) {
  +                    mailbox.setFlags(flags, false, uid, directive.isSilent());
  +                }
  +                else if (directive.getSign() > 0) {
  +                    mailbox.setFlags(flags, true, uid, directive.isSilent());
  +                }
  +                else {
  +                    mailbox.replaceFlags(flags, uid, directive.isSilent());
                   }
  +//                SimpleImapMessage imapMessage = mailbox.getMessage( uid );
  +//                storeFlags( imapMessage, directive, flags );
  +//                mailbox.updateMessage( imapMessage );
  +//
  +//                if ( ! directive.isSilent() ) {
  +//                    StringBuffer out = new StringBuffer( "FLAGS " );
  +//                    out.append( MessageFlags.format(imapMessage.getFlags()) );
  +//                    response.fetchResponse( msn, out.toString() );
  +//                }
               }
           }
   
  -        session.unsolicitedResponses( response );
  +        boolean omitExpunged = (!useUids);
  +        session.unsolicitedResponses( response, omitExpunged );
           response.commandComplete( this );
       }
   
  
  
  
  1.1                  james-server/proposals/imap2/java/org/apache/james/imapserver/commands/IdRange.java
  
  Index: IdRange.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache", "Jakarta", "JAMES" and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  package org.apache.james.imapserver.commands;
  
  /**
   * Represents a range of UID values.
   */
  public class IdRange {
  
      private long _lowVal;
      private long _highVal;
  
      public IdRange(long singleVal) {
          _lowVal = singleVal;
          _highVal = singleVal;
      }
  
      public IdRange(long lowVal, long highVal) {
          _lowVal = lowVal;
          _highVal = highVal;
      }
  
      public long getLowVal() {
          return _lowVal;
      }
  
      public long getHighVal() {
          return _highVal;
      }
  
      public boolean includes(long uid) {
          return _lowVal <= uid && uid <= _highVal;
      }
  
  }
  
  
  
  1.1                  james-server/proposals/imap2/java/org/apache/james/imapserver/commands/MsnRange.java
  
  Index: MsnRange.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache", "Jakarta", "JAMES" and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  package org.apache.james.imapserver.commands;
  
  /**
   * Represents a range of Message Sequence Numbers.
   */
  public class MsnRange {
  
      private int _lowVal;
      private int _highVal;
  
      public MsnRange(int singleVal) {
          _lowVal = singleVal;
          _highVal = singleVal;
      }
  
      public MsnRange(int lowVal, int highVal) {
          _lowVal = lowVal;
          _highVal = highVal;
      }
  
      public int getLowVal() {
          return _lowVal;
      }
  
      public int getHighVal() {
          return _highVal;
      }
  
      public boolean includes(int msn) {
          return _lowVal <= msn && msn <= _highVal;
      }
  
  }
  
  
  
  1.10      +18 -16    james-server/proposals/imap2/java/org/apache/james/imapserver/store/ImapMailbox.java
  
  Index: ImapMailbox.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/store/ImapMailbox.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ImapMailbox.java	13 Jul 2003 12:04:29 -0000	1.9
  +++ ImapMailbox.java	21 Jul 2003 23:31:06 -0000	1.10
  @@ -59,6 +59,8 @@
   package org.apache.james.imapserver.store;
   
   import org.apache.james.core.MailImpl;
  +import org.apache.james.imapserver.commands.IdSet;
  +import org.apache.james.imapserver.commands.IdRange;
   
   import javax.mail.internet.MimeMessage;
   import javax.mail.search.SearchTerm;
  @@ -82,8 +84,6 @@
   
       String getFullName();
   
  -    Flags getAllowedFlags();
  -    
       Flags getPermanentFlags();
   
       int getMessageCount();
  @@ -92,19 +92,23 @@
   
       long getUidValidity();
   
  -    long getFirstUnseen();
  +    int getFirstUnseen();
   
  -    int getMsn( long uid ) throws MailboxException;
  +    int getUnseenCount();
   
       boolean isSelectable();
   
       long getUidNext();
   
  -    int getUnseenCount();
  +    long appendMessage( MimeMessage message, Flags flags, Date internalDate );
   
  -    SimpleImapMessage createMessage( MimeMessage message, Flags flags, Date internalDate );
  +    void deleteAllMessages();
   
  -    void updateMessage( SimpleImapMessage message ) throws MailboxException;
  +    void expunge() throws MailboxException;
  +
  +    void addListener(MailboxListener listener);
  +
  +    void removeListener(MailboxListener listener);
   
       void store( MailImpl mail) throws Exception;
   
  @@ -112,17 +116,15 @@
   
       long[] getMessageUids();
   
  -    void deleteMessage( long uid );
  -    
  -    void expunge() throws MailboxException;
  -
  -    void addListener(MailboxListener listener);
  -
  -    void removeListener(MailboxListener listener);
  -
       long[] search(SearchTerm searchTerm);
   
       void copyMessage( long uid, ImapMailbox toMailbox )
               throws MailboxException;
  +
  +    void setFlags(Flags flags, boolean value, long uid, boolean silent) throws MailboxException;
  +
  +    void replaceFlags(Flags flags, long uid, boolean silent) throws MailboxException;
  +
  +    int getMsn( long uid ) throws MailboxException;
   
   }
  
  
  
  1.9       +81 -59    james-server/proposals/imap2/java/org/apache/james/imapserver/store/InMemoryStore.java
  
  Index: InMemoryStore.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/store/InMemoryStore.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- InMemoryStore.java	13 Jul 2003 12:04:29 -0000	1.8
  +++ InMemoryStore.java	21 Jul 2003 23:31:06 -0000	1.9
  @@ -61,21 +61,14 @@
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.james.core.MailImpl;
   import org.apache.james.imapserver.ImapConstants;
  +import org.apache.james.imapserver.commands.IdSet;
  +import org.apache.james.imapserver.commands.IdRange;
   
   import javax.mail.internet.MimeMessage;
   import javax.mail.search.SearchTerm;
   import javax.mail.MessagingException;
   import javax.mail.Flags;
  -import java.util.ArrayList;
  -import java.util.Collection;
  -import java.util.Collections;
  -import java.util.Date;
  -import java.util.Iterator;
  -import java.util.Map;
  -import java.util.StringTokenizer;
  -import java.util.TreeMap;
  -import java.util.List;
  -import java.util.LinkedList;
  +import java.util.*;
   
   /**
    * A simple in-memory implementation of {@link ImapStore}, used for testing
  @@ -250,7 +243,7 @@
           protected String name;
           private boolean isSelectable = false;
   
  -        private Map mailMessages = new TreeMap();
  +        private List mailMessages = new LinkedList();
           private long nextUid = 1;
           private long uidValidity;
   
  @@ -302,13 +295,8 @@
               return parent.getFullName() + HIERARCHY_DELIMITER_CHAR + name;
           }
   
  -        public Flags getAllowedFlags()
  -        {
  -            return PERMANENT_FLAGS;
  -        }
  -
           public Flags getPermanentFlags() {
  -            return getAllowedFlags();
  +            return PERMANENT_FLAGS;
           }
   
           public int getMessageCount()
  @@ -329,9 +317,8 @@
           public int getUnseenCount()
           {
               int count = 0;
  -            Iterator iter = mailMessages.values().iterator();
  -            while (iter.hasNext()) {
  -                SimpleImapMessage message = (SimpleImapMessage) iter.next();
  +            for (int i = 0; i < mailMessages.size(); i++) {
  +                SimpleImapMessage message = (SimpleImapMessage) mailMessages.get(i);
                   if (! message.getFlags().contains(Flags.Flag.SEEN)) {
                       count++;
                   }
  @@ -339,13 +326,12 @@
               return count;
           }
   
  -        public long getFirstUnseen()
  +        public int getFirstUnseen()
           {
  -            Iterator iter = mailMessages.values().iterator();
  -            while (iter.hasNext()) {
  -                SimpleImapMessage message = (SimpleImapMessage) iter.next();
  +            for (int i = 0; i < mailMessages.size(); i++) {
  +                SimpleImapMessage message = (SimpleImapMessage) mailMessages.get(i);
                   if (! message.getFlags().contains(Flags.Flag.SEEN)) {
  -                    return message.getUid();
  +                    return i + 1;
                   }
               }
               return -1;
  @@ -358,12 +344,10 @@
   
           public int getMsn( long uid ) throws MailboxException
           {
  -            Collection keys = mailMessages.keySet();
  -            Iterator iterator = keys.iterator();
  -            for ( int msn = 1; iterator.hasNext(); msn++ ) {
  -                Long messageUid = ( Long ) iterator.next();
  -                if ( messageUid.longValue() == uid ) {
  -                    return msn;
  +            for (int i = 0; i < mailMessages.size(); i++) {
  +                SimpleImapMessage message = (SimpleImapMessage) mailMessages.get(i);
  +                if (message.getUid() == uid) {
  +                    return i + 1;
                   }
               }
               throw new MailboxException( "No such message." );
  @@ -379,7 +363,7 @@
               isSelectable = selectable;
           }
   
  -        public SimpleImapMessage createMessage( MimeMessage message,
  +        public long appendMessage( MimeMessage message,
                                             Flags flags,
                                             Date internalDate )
           {
  @@ -391,28 +375,64 @@
                                                          internalDate, uid );
               setupLogger( imapMessage );
   
  -            mailMessages.put( new Long( uid ), imapMessage );
  -            
  -            // Notify all the listeners of the pending delete
  +            mailMessages.add(imapMessage);
  +            int newMsn = mailMessages.size();
  +
  +            // Notify all the listeners of the new message
               synchronized (_mailboxListeners) {
                   for (int j = 0; j < _mailboxListeners.size(); j++) {
                       MailboxListener listener = (MailboxListener) _mailboxListeners.get(j);
                       listener.added(uid);
                   }
               }
  -            
  -            return imapMessage;
  +
  +            return uid;
           }
   
  -        public void updateMessage( SimpleImapMessage message )
  -                throws MailboxException
  -        {
  +        public void setFlags(Flags flags, boolean value, long uid, boolean silent) throws MailboxException {
  +            SimpleImapMessage message = getMessage(uid);
  +            if (message == null) {
  +                throw new MailboxException( "Message doesn't exist" );
  +            }
  +
  +            if (value) {
  +                message.getFlags().add(flags);
  +            } else {
  +                message.getFlags().remove(flags);
  +            }
  +
  +            // TODO - this doesn't send silent updates to *any* listeners
  +            // I think "silence" is supposed to be restricted to the session sending the command?.
  +            if (! silent) {
  +                notifyFlagUpdate(uid, message.getFlags());
  +            }
  +        }
   
  -            Long key = new Long( message.getUid() );
  -            if ( ! mailMessages.containsKey( key ) ) {
  +        private void notifyFlagUpdate(long uid, Flags flags) throws MailboxException {
  +            synchronized(_mailboxListeners) {
  +                for (int i = 0; i < _mailboxListeners.size(); i++) {
  +                    MailboxListener listener = (MailboxListener) _mailboxListeners.get(i);
  +
  +                    listener.flagsUpdated(uid, flags);
  +                }
  +            }
  +        }
  +
  +        public void replaceFlags(Flags flags, long uid, boolean silent) throws MailboxException {
  +            SimpleImapMessage message = getMessage(uid);
  +            if (message == null) {
                   throw new MailboxException( "Message doesn't exist" );
               }
  -            mailMessages.put( key, message );
  +            message.getFlags().remove(MessageFlags.ALL_FLAGS);
  +            message.getFlags().add(flags);
  +
  +            if (! silent) {
  +                notifyFlagUpdate(uid, message.getFlags());
  +            }
  +        }
  +
  +        public void deleteAllMessages() {
  +            mailMessages.clear();
           }
   
           public void store( MailImpl mail )
  @@ -421,38 +441,41 @@
               MimeMessage message = mail.getMessage();
               Date internalDate = new Date();
               Flags flags = new Flags();
  -            createMessage( message, flags, internalDate );
  +            appendMessage( message, flags, internalDate );
           }
   
           public SimpleImapMessage getMessage( long uid )
           {
  -            return (SimpleImapMessage)mailMessages.get( new Long(uid ) );
  +            for (int i = 0; i < mailMessages.size(); i++) {
  +                SimpleImapMessage message = (SimpleImapMessage) mailMessages.get(i);
  +                if (message.getUid() == uid) {
  +                    return message;
  +                }
  +            }
  +            return null;
           }
   
           public long[] getMessageUids()
           {
               long[] uids = new long[ mailMessages.size() ];
  -            Collection keys = mailMessages.keySet();
  -            Iterator iterator = keys.iterator();
  -            for ( int i = 0; iterator.hasNext(); i++ ) {
  -                Long key = ( Long ) iterator.next();
  -                uids[i] = key.longValue();
  +            for (int i = 0; i < mailMessages.size(); i++) {
  +                SimpleImapMessage message = (SimpleImapMessage) mailMessages.get(i);
  +                uids[i] = message.getUid();
               }
               return uids;
           }
   
  -        public void deleteMessage( long uid )
  +        private void deleteMessage( long uid )
           {
  -            mailMessages.remove( new Long( uid ) );
  +            SimpleImapMessage message = getMessage(uid);
  +            mailMessages.remove(message);
           }
   
           public long[] search(SearchTerm searchTerm) {
               ArrayList matchedMessages = new ArrayList();
   
  -            long[] allUids = getMessageUids();
  -            for ( int i = 0; i < allUids.length; i++ ) {
  -                long uid = allUids[i];
  -                SimpleImapMessage message = getMessage( uid );
  +            for (int i = 0; i < mailMessages.size(); i++) {
  +                SimpleImapMessage message = (SimpleImapMessage) mailMessages.get(i);
                   if ( searchTerm.match( message.getMimeMessage() ) ) {
                       matchedMessages.add( message );
                   }
  @@ -483,7 +506,7 @@
               newFlags.add( originalMessage.getFlags() );
               Date newDate = originalMessage.getInternalDate();
   
  -            toMailbox.createMessage( newMime, newFlags, newDate);
  +            toMailbox.appendMessage( newMime, newFlags, newDate);
           }
   
           public void expunge() throws MailboxException {
  @@ -494,7 +517,6 @@
                   SimpleImapMessage message = getMessage(uid);
                   if (message.getFlags().contains(Flags.Flag.DELETED)) {
                       expungeMessage(uid);
  -
                   }
               }
           }
  
  
  
  1.2       +4 -0      james-server/proposals/imap2/java/org/apache/james/imapserver/store/MailboxListener.java
  
  Index: MailboxListener.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/store/MailboxListener.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MailboxListener.java	13 Jul 2003 06:04:56 -0000	1.1
  +++ MailboxListener.java	21 Jul 2003 23:31:06 -0000	1.2
  @@ -57,9 +57,13 @@
    */
   package org.apache.james.imapserver.store;
   
  +import javax.mail.Flags;
  +
   public interface MailboxListener {
       // TODO shouldn't have exceptions here
       void expunged(long uid) throws MailboxException;
       
       void added(long uid);
  +
  +    void flagsUpdated(long uid, Flags flags) throws MailboxException;
   }
  
  
  
  1.6       +6 -1      james-server/proposals/imap2/java/org/apache/james/imapserver/store/SimpleImapMessage.java
  
  Index: SimpleImapMessage.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/java/org/apache/james/imapserver/store/SimpleImapMessage.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SimpleImapMessage.java	13 Jul 2003 12:04:29 -0000	1.5
  +++ SimpleImapMessage.java	21 Jul 2003 23:31:06 -0000	1.6
  @@ -82,6 +82,11 @@
       private long uid;
       private SimpleMessageAttributes attributes;
   
  +    public SimpleImapMessage(MimeMessage mimeMessage, Date internalDate, long uid)
  +            throws MessagingException {
  +        this(mimeMessage, mimeMessage.getFlags(), internalDate, uid);
  +    }
  +
       SimpleImapMessage( MimeMessage mimeMessage, Flags flags,
                    Date internalDate, long uid )
       {
  
  
  
  1.8       +22 -11    james-server/proposals/imap2/test/org/apache/james/imapserver/CommandParserTest.java
  
  Index: CommandParserTest.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/test/org/apache/james/imapserver/CommandParserTest.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- CommandParserTest.java	8 Mar 2003 21:13:57 -0000	1.7
  +++ CommandParserTest.java	21 Jul 2003 23:31:06 -0000	1.8
  @@ -60,6 +60,7 @@
   
   import org.apache.james.imapserver.commands.CommandParser;
   import org.apache.james.imapserver.commands.IdSet;
  +import org.apache.james.imapserver.commands.IdRange;
   
   import junit.framework.TestCase;
   
  @@ -229,35 +230,45 @@
           String testRequest = "8 25 1:4 33:* 2,3,4 1,4:6,8:* ";
           ImapRequestLineReader request = getRequest( testRequest );
   
  -        IdSet idSet;
  -        idSet = parser.set( request );
  +        IdRange[] idSet;
  +        idSet = parser.parseIdRange( request );
           checkSet( idSet, new long[]{8}, new long[]{0, 2, 7, 9, 20, Long.MAX_VALUE } );
   
  -        idSet = parser.set( request );
  +        idSet = parser.parseIdRange( request );
           checkSet( idSet, new long[]{ 25 }, new long[]{ 0, 5, 20, 30, Long.MAX_VALUE } );
   
  -        idSet = parser.set( request );
  +        idSet = parser.parseIdRange( request );
           checkSet( idSet, new long[]{ 1, 2, 3, 4 }, new long[]{0, 5, 10 } );
   
  -        idSet = parser.set( request );
  +        idSet = parser.parseIdRange( request );
           checkSet( idSet, new long[]{ 33, 35, 100, 1000, Long.MAX_VALUE}, new long[]{0, 1, 32});
   
  -        idSet = parser.set( request );
  +        idSet = parser.parseIdRange( request );
           checkSet( idSet, new long[]{ 2,3,4}, new long[]{0, 1, 5,8 });
   
  -        idSet = parser.set( request );
  +        idSet = parser.parseIdRange( 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 )
  +    private void checkSet( IdRange[] idSet, long[] includes, long[] excludes )
       {
           for ( int i = 0; i < includes.length; i++ ) {
  -            assertTrue( idSet.includes( includes[i] ));
  +            assertTrue( includes( idSet, includes[i] ));
           }
           for ( int i = 0; i < excludes.length; i++ ) {
  -            assertTrue( ! idSet.includes( excludes[i] ));
  +            assertTrue( ! includes( idSet, excludes[i] ));
           }
  +    }
  +
  +    private boolean includes(IdRange[] idSet, long value) {
  +        for (int i = 0; i < idSet.length; i++) {
  +            IdRange idRange = idSet[i];
  +            if (idRange.includes(value)) {
  +                return true;
  +            }
  +        }
  +        return false;
       }
   
       /**
  
  
  
  1.6       +112 -6    james-server/proposals/imap2/test/org/apache/james/imapserver/ImapMailboxTest.java
  
  Index: ImapMailboxTest.java
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/test/org/apache/james/imapserver/ImapMailboxTest.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ImapMailboxTest.java	13 Jul 2003 12:04:29 -0000	1.5
  +++ ImapMailboxTest.java	21 Jul 2003 23:31:06 -0000	1.6
  @@ -90,7 +90,7 @@
   
       public void testAppend() throws Exception
       {
  -        ImapMailbox mailbox = getMailbox();
  +        ImapMailbox mailbox = getMailbox("test");
   
           Flags flags = new Flags();
           flags.add(Flags.Flag.FLAGGED);
  @@ -130,15 +130,121 @@
                   new MimeMessageByteArraySource( "messageContent:" + System.currentTimeMillis(),
                                                   messageContent.getBytes());
           MimeMessage message = new MimeMessageWrapper( source );
  -        SimpleImapMessage imapMessage = mailbox.createMessage( message, flags, datetime );
  -        return imapMessage.getUid();
  +        return mailbox.appendMessage( message, flags, datetime );
       }
   
  -    private ImapMailbox getMailbox() throws MailboxException
  +    public void testName() throws Exception {
  +        checkName("named");
  +        checkName("NaMeD");
  +        checkName("Na_94Eg");
  +    }
  +
  +    private void checkName(String mailboxName) throws Exception {
  +        ImapMailbox mailbox = getMailbox(mailboxName);
  +        assertEquals(mailboxName, mailbox.getName());
  +        assertEquals(ImapConstants.USER_NAMESPACE + ImapConstants.HIERARCHY_DELIMITER + mailboxName,
  +                mailbox.getFullName());
  +    }
  +
  +    public void testMailboxFlags() throws Exception {
  +        Flags expectedFlags = new Flags();
  +        expectedFlags.add(Flags.Flag.ANSWERED);
  +        expectedFlags.add(Flags.Flag.DELETED);
  +        expectedFlags.add(Flags.Flag.DRAFT);
  +        expectedFlags.add(Flags.Flag.FLAGGED);
  +        expectedFlags.add(Flags.Flag.SEEN);
  +
  +        ImapMailbox mailbox = getMailbox("test");
  +
  +        Flags permanentFlags = mailbox.getPermanentFlags();
  +        assertTrue(permanentFlags.contains(expectedFlags));
  +        assertTrue(! permanentFlags.contains(Flags.Flag.RECENT));
  +    }
  +
  +    public void testMessageCount() throws Exception
  +    {
  +        ImapMailbox mailbox = getMailbox("messagecount");
  +        assertEquals(0, mailbox.getMessageCount());
  +
  +        appendMessage(mailbox);
  +        appendMessage(mailbox);
  +        assertEquals(2, mailbox.getMessageCount());
  +
  +        appendMessage(mailbox);
  +        assertEquals(3, mailbox.getMessageCount());
  +
  +        mailbox.deleteAllMessages();
  +        assertEquals(0, mailbox.getMessageCount());
  +    }
  +
  +    public void testUnseen() throws Exception {
  +        ImapMailbox mailbox = getMailbox("firstUnseen");
  +        assertEquals(-1, mailbox.getFirstUnseen());
  +        assertEquals(0, mailbox.getUnseenCount());
  +
  +        long uid1 = appendMessage(mailbox);
  +        long uid2 = appendMessage(mailbox);
  +        assertEquals(1, mailbox.getFirstUnseen());
  +        assertEquals(2, mailbox.getUnseenCount());
  +
  +        // Flag the first as seen
  +        mailbox.setFlags(new Flags(Flags.Flag.SEEN), true, uid1, true);
  +        assertEquals(2, mailbox.getFirstUnseen());
  +        assertEquals(1, mailbox.getUnseenCount());
  +
  +        // Flag the second as seen
  +        mailbox.setFlags(new Flags(Flags.Flag.SEEN), true, uid2, true);
  +        assertEquals(-1, mailbox.getFirstUnseen());
  +        assertEquals(0, mailbox.getUnseenCount());
  +
  +        // Unset the seen flag on the first
  +        mailbox.setFlags(new Flags(Flags.Flag.SEEN), false, uid1, true);
  +        assertEquals(1, mailbox.getFirstUnseen());
  +        assertEquals(1, mailbox.getUnseenCount());
  +    }
  +
  +    public void testSelectable() throws Exception {
  +        ImapStore store = new InMemoryStore();
  +        ImapMailbox root = store.getMailbox( ImapConstants.USER_NAMESPACE );
  +        ImapMailbox selectable = store.createMailbox( root, "selectable", true );
  +        assertTrue(selectable.isSelectable());
  +
  +        ImapMailbox nonSelectable = store.createMailbox(root, "nonselectable", false);
  +        assertTrue(! nonSelectable.isSelectable());
  +    }
  +
  +    public void testUidNext() throws Exception {
  +        ImapMailbox mailbox = getMailbox("uidnext");
  +        long first = mailbox.getUidNext();
  +        assertTrue(first != 0);
  +        assertEquals(first, appendMessage(mailbox));
  +        long second = mailbox.getUidNext();
  +        assertEquals(second, appendMessage(mailbox));
  +        assertTrue(first < second);
  +    }
  +
  +    private long appendMessage(ImapMailbox mailbox) {
  +        Date datetime = new Date();
  +        String message =
  +        "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)\r\n" +
  +        "From: Fred Foobar <foobar@Blurdybloop.COM>\r\n" +
  +        "Subject: afternoon meeting\r\n" +
  +        "To: mooch@owatagu.siam.edu\r\n" +
  +        "Message-Id: <B27397-0100000@Blurdybloop.COM>\r\n" +
  +        "MIME-Version: 1.0\r\n" +
  +        "Content-Type: TEXT/PLAIN; CHARSET=US-ASCII\r\n" +
  +        "\r\n" +
  +        "Hello Joe, do you think we can meet at 3:30 tomorrow?\r\n" +
  +        "\r\n";
  +
  +        return appendMessage( message, new Flags(), datetime, mailbox );
  +    }
  +
  +    private ImapMailbox getMailbox(String mailboxName) throws MailboxException
       {
           ImapStore store = new InMemoryStore();
           ImapMailbox root = store.getMailbox( ImapConstants.USER_NAMESPACE );
  -        ImapMailbox test = store.createMailbox( root, "test", true );
  +        ImapMailbox test = store.createMailbox( root, mailboxName, true );
           return test;
       }
   
  
  
  
  1.2       +4 -4      james-server/proposals/imap2/test/org/apache/james/imapserver/Store.test
  
  Index: Store.test
  ===================================================================
  RCS file: /home/cvs/james-server/proposals/imap2/test/org/apache/james/imapserver/Store.test,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Store.test	3 Dec 2002 14:00:13 -0000	1.1
  +++ Store.test	21 Jul 2003 23:31:06 -0000	1.2
  @@ -7,13 +7,13 @@
   S: f1 OK FETCH completed
   
   #Simple store
  -C: f1 STORE 1 FLAGS (\Deleted)
  +C: f2 STORE 1 FLAGS (\Deleted)
   S: \* 1 FETCH \(FLAGS \(\\Deleted\)\)
  -S: f1 OK STORE completed
  +S: f2 OK STORE completed
   
  -C: f1 FETCH 1 (FLAGS)
  +C: f3 FETCH 1 (FLAGS)
   S: \* 1 FETCH \(FLAGS \(\\Deleted\)\)
  -S: f1 OK FETCH completed
  +S: f3 OK FETCH completed
   
   #Override previous value (silent)
   C: f2 STORE 1 FLAGS.SILENT (\Draft \Flagged)
  
  
  

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


Mime
View raw message