darrell     2002/11/24 17:11:45

  Modified:    proposals/imap2 build-test.xml
               proposals/imap2/java/org/apache/james/imapserver
                        ImapHandler.java
               proposals/imap2/java/org/apache/james/imapserver/commands
                        AuthenticateCommand.java CapabilityCommand.java
                        CommandTemplate.java CreateCommand.java
                        DeleteCommand.java ImapCommand.java
                        ListCommand.java LoginCommand.java
                        LogoutCommand.java NoopCommand.java
                        RenameCommand.java SelectCommand.java
               proposals/imap2/java/org/apache/james/imapserver/store
                        ImapMailbox.java InMemoryStore.java
               proposals/imap2/test/org/apache/james/imapserver
                        Authenticate.test Capability.test Login.test
                        Logout.test
  Added:       proposals/imap2/java/org/apache/james/imapserver
                        ImapRequestLineReader.java
               proposals/imap2/java/org/apache/james/imapserver/commands
                        CommandParser.java StatusCommand.java
               proposals/imap2/test/org/apache/james/imapserver
                        CommandParserTest.java
  Removed:     proposals/imap2/java/org/apache/james/imapserver
                        ImapRequestParser.java
               proposals/imap2/test/org/apache/james/imapserver
                        ImapRequestParserTest.java
  Log:
  IMAP Proposal updates.
  
  * Cleaned up request parsing infrastructure
      - moved imap-specific stuff into o.a.j.imapserver.commands.CommandParser.
      - command implementations can extend this to provide command-specific parsing.
      - Added ImapRequestLineReader which is a convenience wrapper around
        the socket reader.
  * Better handling of argument syntax
      - "literal" encoding of "string" arguments.
        (eg. "{<number-of-bytes>}CRLF<bytes>" )
      - escaped characters in quotes
        ( eg. "middle \"word\" quoted then \\ backslash." )
      - validation of characters in "atom" argument values.
  
  Revision  Changes    Path
  1.2       +1 -1      jakarta-james/proposals/imap2/build-test.xml
  
  Index: build-test.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/imap2/build-test.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- build-test.xml    22 Nov 2002 02:09:50 -0000      1.1
  +++ build-test.xml    25 Nov 2002 01:11:44 -0000      1.2
  @@ -143,7 +143,7 @@
               </classpath>
               <formatter type="plain" usefile="false"/>
               <test name="org.apache.james.imapserver.ImapHostTest"/>
  -            <test name="org.apache.james.imapserver.ImapRequestParserTest"/>
  +            <test name="org.apache.james.imapserver.CommandParserTest"/>
               <test name="org.apache.james.imapserver.ImapStoreTest"/>
           </junit>
       </target>
  
  
  
  1.2       +14 -6     
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/ImapHandler.java
  
  Index: ImapHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/ImapHandler.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ImapHandler.java  22 Nov 2002 02:09:50 -0000      1.1
  +++ ImapHandler.java  25 Nov 2002 01:11:44 -0000      1.2
  @@ -15,6 +15,7 @@
   import org.apache.james.Constants;
   import org.apache.james.imapserver.commands.ImapCommand;
   import org.apache.james.imapserver.commands.ImapCommandFactory;
  +import org.apache.james.imapserver.commands.CommandParser;
   import org.apache.james.imapserver.store.ImapMailbox;
   import org.apache.james.services.MailRepository;
   import org.apache.james.services.User;
  @@ -46,7 +47,8 @@
   
       private String softwaretype = "JAMES IMAP4rev1 Server " + 
Constants.SOFTWARE_VERSION;
       private ImapResponse untaggedResponse;
  -    private ImapRequestParser request;
  +    private ImapRequestLineReader request;
  +    private CommandParser parser = new CommandParser();
       private ImapSession session;
       private ImapCommandFactory imapCommands = new ImapCommandFactory();
   
  @@ -218,7 +220,7 @@
                       .append( " ready" );
               untaggedResponse.okResponse( null, responseBuffer.toString() );
   
  -            request = new ImapRequestParser( in );
  +            request = new ImapRequestLineReader( in );
               session = new ImapSessionImpl();
   
               theWatchdog.start();
  @@ -371,31 +373,37 @@
        *
        * @return whether additional commands are expected.
        */
  -    private boolean parseCommand()
  +    private boolean parseCommand() throws ProtocolException
       {
  -        if ( !request.nextRequest() ) {
  +        try {
  +            request.nextChar();
  +        }
  +        catch ( ProtocolException e ) {
               return false;
           }
           ImapResponse response = new ImapResponse( out );
           String tag = null;
           String commandName = null;
  +
           try {
  -            tag = request.tag();
  +            tag = parser.tag( request );
           }
           catch ( ProtocolException e ) {
               response.badResponse( REQUEST_SYNTAX );
               return true;
           }
   
  +        System.out.println( "Got <tag>: " + tag );
           response.setTag( tag );
           try {
  -            commandName = request.atom();
  +            commandName = parser.atom( request );
           }
           catch ( ProtocolException e ) {
               response.commandError( REQUEST_SYNTAX );
               return true;
           }
   
  +        System.out.println( "Got <command>: " + commandName );
           ImapCommand command = imapCommands.getCommand( commandName );
           if ( command == null )
           {
  
  
  
  1.1                  
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/ImapRequestLineReader.java
  
  Index: ImapRequestLineReader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.imapserver;
  
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.Reader;
  import java.util.StringTokenizer;
  
  /**
   * Wraps the client input reader with a bunch of convenience methods, allowing 
lookahead=1
   * on the underlying character stream.
   *
   * @author  Darrell DeBoer <[EMAIL PROTECTED]>
   *
   * @version $Revision: 1.1 $
   */
  public class ImapRequestLineReader
  {
      private Reader reader;
  
      private boolean nextSeen = false;
      private char nextChar; // unknown
  
      ImapRequestLineReader( Reader reader )
      {
          this.reader = reader;
      }
  
      /**
       * Reads the next regular, non-space character in the current line. Spaces are 
skipped
       * over, but end-of-line characters will cause a {@link ProtocolException} to be 
thrown.
       * This method will continue to return
       * the same character until the {@link #consume()} method is called.
       * @return The next non-space character.
       * @throws ProtocolException If the end-of-line or end-of-stream is reached.
       */
      public char nextWordChar() throws ProtocolException
      {
          char next = nextChar();
          while ( next == ' ' ) {
              consume();
              next = nextChar();
          }
  
          if ( next == '\r' || next == '\n' ) {
              // Move to the next line, and throw exception.
              eol();
              throw new ProtocolException( "Missing argument." );
          }
  
          return next;
      }
  
      /**
       * Reads the next character in the current line. This method will continue to 
return
       * the same character until the {@link #consume()} method is called.
       * @return The next character.
       * @throws ProtocolException If the end-of-stream is reached.
       */
      public char nextChar() throws ProtocolException
      {
          if ( ! nextSeen ) {
              int next = -1;
  
              try {
                  next = reader.read();
              }
              catch ( IOException e ) {
                  throw new ProtocolException( "Error reading from stream." );
              }
              if ( next == -1 ) {
                  throw new ProtocolException( "Unexpected end of stream." );
              }
              else {
             }
  
              nextSeen = true;
              nextChar = ( char ) next;
          }
          return nextChar;
      }
  
      /**
       * Moves the request line reader to the next line, by consuming any
       * trailing whitespace, and CRLF.
       * @throws ProtocolException If more non-space tokens are found in this line,
       *                           or the end-of-file is reached. All extra tokens are 
consumed regardless.
       */
      public void eol() throws ProtocolException
      {
          char next = nextChar();
  
          // Ignore trailing spaces.
          while ( next == ' ' ) {
              consume();
              next = nextChar();
          }
  
          // handle DOS and unix end-of-lines
          if ( next == '\r' ) {
              consume();
              next = nextChar();
          }
  
          // Need to consume until the end-of-line, regardless.
          while ( consume() != '\n' ) {
              // keep on consuming
          }
  
          // Check if we found extra characters.
          if ( next != '\n' ) {
              throw new ProtocolException( "Expected end-of-line, found more 
characters.");
          }
      }
  
      /**
       * Consumes the current character in the reader, so that subsequent calls to the 
request will
       * provide a new character. This method does *not* read the new character, or 
check if
       * such a character exists. If no current character has been seen, the method 
moves to
       * the next character, consumes it, and moves on to the subsequent one.
       * @throws ProtocolException if a the current character can't be obtained (eg 
we're at
       *                            end-of-file).
       */
      public char consume() throws ProtocolException
      {
          char current = nextChar();
          nextSeen = false;
          nextChar = 0;
          return current;
      }
  
  
      /**
       * Reads and consumes a number of characters from the underlying reader,
       * filling the char array provided.
       * @param holder A char array which will be filled with chars read from the 
underlying reader.
       * @throws ProtocolException If a char can't be read into each array element.
       */
      public void read( char[] holder ) throws ProtocolException
      {
          try {
              reader.read( holder );
          }
          catch ( IOException e ) {
              throw new ProtocolException( "Error reading from stream." );
          }
      }
  }
  
  
  
  1.2       +5 -5      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/AuthenticateCommand.java
  
  Index: AuthenticateCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/AuthenticateCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AuthenticateCommand.java  22 Nov 2002 02:09:51 -0000      1.1
  +++ AuthenticateCommand.java  25 Nov 2002 01:11:44 -0000      1.2
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  @@ -25,13 +25,13 @@
       public static final String ARGS = "<auth_type> *(CRLF base64)";
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session
                                 ) throws ProtocolException
       {
  -        String authType = request.astring();
  -        request.endLine();
  +        String authType = parser.astring( request );
  +        parser.endLine( request );
   
           response.commandFailed( this, "Unsupported authentication mechanism '" +
                                         authType + "'" );
  
  
  
  1.2       +8 -4      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CapabilityCommand.java
  
  Index: CapabilityCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CapabilityCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CapabilityCommand.java    22 Nov 2002 02:09:51 -0000      1.1
  +++ CapabilityCommand.java    25 Nov 2002 01:11:44 -0000      1.2
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  @@ -27,15 +27,19 @@
       public static final String CAPABILITY_RESPONSE = NAME + SP + VERSION;
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException
       {
  -        request.endLine();
  +        System.out.println( "About to do parser.endLine()" );
  +        parser.endLine( request );
  +        System.out.println( "Completed parser.endLine()" );
           response.untaggedResponse( CAPABILITY_RESPONSE );
  +        System.out.println( "Sent untagged response." );
           session.unsolicitedResponses( response );
           response.commandComplete( this );
  +        System.out.println( "Sent capability response." );
       }
   
       /** @see ImapCommand#getName */
  
  
  
  1.2       +10 -99    
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CommandTemplate.java
  
  Index: CommandTemplate.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CommandTemplate.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CommandTemplate.java      22 Nov 2002 02:09:51 -0000      1.1
  +++ CommandTemplate.java      25 Nov 2002 01:11:44 -0000      1.2
  @@ -11,7 +11,7 @@
   import org.apache.james.imapserver.AuthorizationException;
   import org.apache.james.imapserver.ImapConstants;
   import org.apache.james.imapserver.store.ImapMailbox;
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ImapSessionState;
  @@ -30,6 +30,8 @@
           extends AbstractLogEnabled
           implements ImapCommand, ImapConstants
   {
  +    protected CommandParser parser = new CommandParser();
  +
       /**
        * By default, valid in any state (unless overridden by subclass.
        * @see org.apache.james.imapserver.commands.ImapCommand#validForState
  @@ -47,7 +49,7 @@
        *
        * @see ImapCommand#process
        */
  -    public void process( ImapRequestParser request,
  +    public void process( ImapRequestLineReader request,
                            ImapResponse response,
                            ImapSession session )
       {
  @@ -76,7 +78,7 @@
        * @param response The server response
        * @param session The current client session
        */
  -    protected abstract void doProcess( ImapRequestParser request,
  +    protected abstract void doProcess( ImapRequestLineReader request,
                                          ImapResponse response,
                                          ImapSession session )
               throws ProtocolException, MailboxException, AuthorizationException;
  @@ -122,99 +124,8 @@
           return session.getHost().getMailbox( session.getUser(), mailboxName, 
mustExist );
       }
   
  -//    /**
  -//     * Logs the command details.
  -//     */
  -//    protected void logCommand( ImapRequestParser request, ImapSession session )
  -//    {
  -//        getLogger().debug( request.getCommand() + " command completed for " +
  -//                           session.getRemoteHost() + "(" +
  -//                           session.getRemoteIP() + ")" );
  -//    }
  -//
  -//    protected ACLMailbox getMailbox( ImapSession session, String mailboxName, 
String command )
  -//    {
  -//        if ( session.getState() == ImapSessionState.SELECTED && 
session.currentMailbox().equals( mailboxName ) ) {
  -//            return session.getCurrentMailbox();
  -//        }
  -//        else {
  -//            try {
  -//                return session.getImapHost().getMailbox( 
session.getCurrentUser(), mailboxName );
  -//            } catch ( MailboxException me ) {
  -//                if ( me.isRemote() ) {
  -//                    session.noResponse( "[REFERRAL " + me.getRemoteServer() + "]" 
+ SP + "Remote mailbox" );
  -//                } else {
  -//                    session.noResponse( command, "Unknown mailbox" );
  -//                    getLogger().info( "MailboxException in method getBox for 
user: "
  -//                                      + session.getCurrentUser() + " mailboxName: 
" + mailboxName + " was "
  -//                                      + me.getMessage() );
  -//                }
  -//                return null;
  -//            }
  -//            catch ( AccessControlException e ) {
  -//                session.noResponse( command, "Unknown mailbox" );
  -//                return null;
  -//            }
  -//        }
  -//    }
  -
  -//    public static String readAstring( StringTokenizer tokens )
  -//    {
  -//        if ( ! tokens.hasMoreTokens() ) {
  -//            throw new RuntimeException( "Not enough tokens" );
  -//        }
  -//        String token = tokens.nextToken();
  -//        Assert.isTrue( token.length() > 0 );
  -//
  -//        StringBuffer astring = new StringBuffer( token );
  -//
  -//        if ( astring.charAt(0) == '\"' ) {
  -//            while ( astring.length() == 1 ||
  -//                    astring.charAt( astring.length() - 1 ) != '\"' ) {
  -//                if ( tokens.hasMoreTokens() ) {
  -//                    astring.append( tokens.nextToken() );
  -//                }
  -//                else {
  -//                    throw new RuntimeException( "Missing closing quote" );
  -//                }
  -//            }
  -//            astring.deleteCharAt( 0 );
  -//            astring.deleteCharAt( astring.length() - 1 );
  -//        }
  -//
  -//        return astring.toString();
  -//    }
  -//
  -//    public String decodeAstring( String rawAstring )
  -//    {
  -//
  -//        if ( rawAstring.length() == 0 ) {
  -//            return rawAstring;
  -//        }
  -//
  -//        if ( rawAstring.startsWith( "\"" ) ) {
  -//            //quoted string
  -//            if ( rawAstring.endsWith( "\"" ) ) {
  -//                if ( rawAstring.length() == 2 ) {
  -//                    return new String(); //ie blank
  -//                }
  -//                else {
  -//                    return rawAstring.substring( 1, rawAstring.length() - 1 );
  -//                }
  -//            }
  -//            else {
  -//                getLogger().error( "Quoted string with no closing quote." );
  -//                return null;
  -//            }
  -//        }
  -//        else {
  -//            //atom
  -//            return rawAstring;
  -//        }
  -//    }
  -//
  -//    public void setArgs( List args )
  -//    {
  -//        this.args = args;
  -//    }
  +    public CommandParser getParser()
  +    {
  +        return parser;
  +    }
   }
  
  
  
  1.2       +5 -5      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CreateCommand.java
  
  Index: CreateCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CreateCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CreateCommand.java        22 Nov 2002 02:09:51 -0000      1.1
  +++ CreateCommand.java        25 Nov 2002 01:11:44 -0000      1.2
  @@ -8,7 +8,7 @@
   package org.apache.james.imapserver.commands;
   
   import org.apache.james.imapserver.AuthorizationException;
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.store.MailboxException;
  @@ -27,13 +27,13 @@
       public static final String ARGS = "<mailbox>";
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException, MailboxException, AuthorizationException
       {
  -        String mailboxName = request.astring();
  -        request.endLine();
  +        String mailboxName = parser.astring( request );
  +        parser.endLine( request );
   
           session.getHost().createMailbox( session.getUser(), mailboxName );
           session.unsolicitedResponses( response );
  
  
  
  1.2       +5 -5      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/DeleteCommand.java
  
  Index: DeleteCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/DeleteCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeleteCommand.java        22 Nov 2002 02:09:51 -0000      1.1
  +++ DeleteCommand.java        25 Nov 2002 01:11:44 -0000      1.2
  @@ -8,7 +8,7 @@
   package org.apache.james.imapserver.commands;
   
   import org.apache.james.imapserver.AuthorizationException;
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.store.MailboxException;
  @@ -27,14 +27,14 @@
       public static final String ARGS = "<mailbox>";
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException, MailboxException, AuthorizationException
       {
   
  -        String mailboxName = request.astring();
  -        request.endLine();
  +        String mailboxName = parser.astring( request );
  +        parser.endLine( request );
   
           session.getHost().deleteMailbox( session.getUser(), mailboxName );
   
  
  
  
  1.2       +3 -3      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/ImapCommand.java
  
  Index: ImapCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/ImapCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ImapCommand.java  22 Nov 2002 02:09:51 -0000      1.1
  +++ ImapCommand.java  25 Nov 2002 01:11:44 -0000      1.2
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ImapSessionState;
  @@ -42,7 +42,7 @@
        * @param response The current server response
        * @param session The current session
        */
  -    void process( ImapRequestParser request,
  +    void process( ImapRequestLineReader request,
                     ImapResponse response,
                     ImapSession session );
   }
  
  
  
  1.2       +42 -6     
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/ListCommand.java
  
  Index: ListCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/ListCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ListCommand.java  22 Nov 2002 02:09:51 -0000      1.1
  +++ ListCommand.java  25 Nov 2002 01:11:44 -0000      1.2
  @@ -8,7 +8,7 @@
   package org.apache.james.imapserver.commands;
   
   import org.apache.james.imapserver.store.ImapMailbox;
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.store.MailboxException;
  @@ -31,15 +31,17 @@
       public static final String NAME = "LIST";
       public static final String ARGS = "<reference-name> 
<mailbox-name-with-wildcards>";
   
  +    private ListCommandParser parser = new ListCommandParser();
  +
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException, MailboxException
       {
  -        String referenceName = request.astring();
  -        String mailboxPattern = request.listMailbox();
  -        request.endLine();
  +        String referenceName = parser.astring( request );
  +        String mailboxPattern = parser.listMailbox( request );
  +        parser.endLine( request );
   
           // Should the #user.userName section be removed from names returned?
           boolean removeUserPrefix;
  @@ -180,6 +182,40 @@
           return ARGS;
       }
   
  +    private class ListCommandParser extends CommandParser
  +    {
  +        private final char[] WILDCARD_CHARS = new char[]{'*', '%'};
  +
  +        /**
  +         * Reads an argument of type "list_mailbox" from the request, which is
  +         * the second argument for a LIST or LSUB command. Valid values are a 
"string"
  +         * argument, an "atom" with wildcard characters.
  +         * @return An argument of type "list_mailbox"
  +         */
  +        public String listMailbox( ImapRequestLineReader request ) throws 
ProtocolException
  +        {
  +            char next = request.nextWordChar();
  +            switch ( next ) {
  +                case '"':
  +                    return consumeQuoted( request );
  +                case '{':
  +                    return consumeLiteral( request );
  +                default:
  +                    return consumeWord( request, new ListCharValidator() );
  +            }
  +        }
  +
  +        private class ListCharValidator extends ATOM_CHARValidator
  +        {
  +            public boolean isValid( char chr )
  +            {
  +                if ( isListWildcard( chr ) ) {
  +                    return true;
  +                }
  +                return super.isValid( chr );
  +            }
  +        }
  +    }
   }
   
   /*
  
  
  
  1.2       +6 -6      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/LoginCommand.java
  
  Index: LoginCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/LoginCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LoginCommand.java 22 Nov 2002 02:09:51 -0000      1.1
  +++ LoginCommand.java 25 Nov 2002 01:11:44 -0000      1.2
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  @@ -26,14 +26,14 @@
       public static final String ARGS = "<userid> <password>";
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException
       {
  -        String userid = request.astring();
  -        String password = request.astring();
  -        request.endLine();
  +        String userid = parser.astring( request );
  +        String password = parser.astring( request );
  +        parser.endLine( request );
   
           if ( session.getUsers().test( userid, password ) ) {
               User user = session.getUsers().getUserByName( userid );
  
  
  
  1.2       +4 -4      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/LogoutCommand.java
  
  Index: LogoutCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/LogoutCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LogoutCommand.java        22 Nov 2002 02:09:51 -0000      1.1
  +++ LogoutCommand.java        25 Nov 2002 01:11:44 -0000      1.2
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  @@ -27,11 +27,11 @@
               "Server logging out";
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session ) throws ProtocolException
       {
  -        request.endLine();
  +        parser.endLine( request );
   
           response.untaggedResponse( BYE_MESSAGE );
           response.commandComplete( this );
  
  
  
  1.2       +4 -4      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/NoopCommand.java
  
  Index: NoopCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/NoopCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- NoopCommand.java  22 Nov 2002 02:09:51 -0000      1.1
  +++ NoopCommand.java  25 Nov 2002 01:11:44 -0000      1.2
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.imapserver.commands;
   
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.ProtocolException;
  @@ -25,11 +25,11 @@
       public static final String ARGS = null;
   
       /** @see org.apache.james.imapserver.commands.CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session ) throws ProtocolException
       {
  -        request.endLine();
  +        parser.endLine( request );
           session.unsolicitedResponses( response );
           response.commandComplete( this );
       }
  
  
  
  1.2       +6 -6      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/RenameCommand.java
  
  Index: RenameCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/RenameCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RenameCommand.java        22 Nov 2002 02:09:51 -0000      1.1
  +++ RenameCommand.java        25 Nov 2002 01:11:44 -0000      1.2
  @@ -8,7 +8,7 @@
   package org.apache.james.imapserver.commands;
   
   import org.apache.james.imapserver.AuthorizationException;
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.store.MailboxException;
  @@ -27,14 +27,14 @@
       public static final String ARGS = "existing-mailbox-name SPACE 
new-mailbox-name";
   
       /** @see CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException, MailboxException, AuthorizationException
       {
  -        String existingName = request.astring();
  -        String newName = request.astring();
  -        request.endLine();
  +        String existingName = parser.astring( request );
  +        String newName = parser.astring( request );
  +        parser.endLine( request );
   
           session.getHost().renameMailbox( session.getUser(), existingName, newName );
   
  
  
  
  1.2       +5 -5      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/SelectCommand.java
  
  Index: SelectCommand.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/SelectCommand.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SelectCommand.java        22 Nov 2002 02:09:51 -0000      1.1
  +++ SelectCommand.java        25 Nov 2002 01:11:44 -0000      1.2
  @@ -8,7 +8,7 @@
   package org.apache.james.imapserver.commands;
   
   import org.apache.james.imapserver.store.ImapMailbox;
  -import org.apache.james.imapserver.ImapRequestParser;
  +import org.apache.james.imapserver.ImapRequestLineReader;
   import org.apache.james.imapserver.ImapResponse;
   import org.apache.james.imapserver.ImapSession;
   import org.apache.james.imapserver.store.MailboxException;
  @@ -27,13 +27,13 @@
       public static final String ARGS = "mailbox";
   
       /** @see org.apache.james.imapserver.commands.CommandTemplate#doProcess */
  -    protected void doProcess( ImapRequestParser request,
  +    protected void doProcess( ImapRequestLineReader request,
                                 ImapResponse response,
                                 ImapSession session )
               throws ProtocolException, MailboxException
       {
  -        String mailboxName = request.astring();
  -        request.endLine();
  +        String mailboxName = parser.astring( request );
  +        parser.endLine( request );
   
           session.deselect();
   
  
  
  
  1.1                  
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/CommandParser.java
  
  Index: CommandParser.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.imapserver.commands;
  
  import org.apache.james.imapserver.ProtocolException;
  import org.apache.james.imapserver.ImapRequestLineReader;
  import org.apache.james.imapserver.store.MessageFlags;
  import org.apache.james.util.Assert;
  
  import java.util.Date;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.text.ParseException;
  
  /**
   *
   * @author  Darrell DeBoer <[EMAIL PROTECTED]>
   *
   * @version $Revision: 1.1 $
   */
  public class CommandParser
  {
      private static final char[] EMPTY_CHAR_ARRAY = new char[0];
  
      /**
       * Reads an argument of type "atom" from the request.
       */
      public String atom( ImapRequestLineReader request ) throws ProtocolException
      {
          return consumeWord( request, new ATOM_CHARValidator() );
      }
  
      /**
       * Reads a command "tag" from the request.
       */
      public String tag(ImapRequestLineReader request) throws ProtocolException
      {
          CharacterValidator validator = new TagCharValidator();
          return consumeWord( request, validator );
      }
  
      /**
       * Reads an argument of type "astring" from the request.
       */
      public String astring(ImapRequestLineReader request) throws ProtocolException
      {
          char next = request.nextWordChar();
          switch ( next ) {
              case '"':
                  return consumeQuoted( request );
              case '{':
                  return consumeLiteral( request );
              default:
                  return atom( request );
          }
      }
  
      /**
       * Reads an argument of type "nstring" from the request.
       */
      public String nstring( ImapRequestLineReader request ) throws ProtocolException
      {
          char next = request.nextWordChar();
          switch ( next ) {
              case '"':
                  return consumeQuoted( request );
              case '{':
                  return consumeLiteral( request );
              default:
                  String value = atom( request );
                  if ( "NIL".equals( value ) ) {
                      return null;
                  }
                  else {
                      throw new ProtocolException( "Invalid nstring value: valid 
values are '\"...\"', '{12} CRLF *CHAR8', and 'NIL'." );
                  }
          }
      }
  
      /**
       * Reads a "date-time" argument from the request.
       */
      public Date dateTime( ImapRequestLineReader request ) throws ProtocolException
      {
          char next = request.nextWordChar();
          String dateString;
          if ( next == '"' ) {
              dateString = consumeQuoted( request );
          }
          else {
              throw new ProtocolException( "DateTime values must be quoted." );
          }
  
          DateFormat dateFormat = new SimpleDateFormat( "dd-MMM-yyyy HH:mm:ss ZZ" );
          try {
              return dateFormat.parse( dateString );
          }
          catch ( ParseException e ) {
              throw new ProtocolException( "Invalid date format." );
          }
      }
  
      /**
       * Reads a "date" argument from the request.
       */
      public Date date( ImapRequestLineReader request ) throws ProtocolException
      {
          char next = request.nextWordChar();
          String dateString;
          if ( next == '"' ) {
              dateString = consumeQuoted( request );
          }
          else {
              dateString = atom( request );
          }
  
          DateFormat dateFormat = new SimpleDateFormat( "dd-MMM-yyyy" );
          try {
              return dateFormat.parse( dateString );
          }
          catch ( ParseException e ) {
              throw new ProtocolException( "Invalid date format." );
          }
      }
  
      /**
       * Reads the next "word from the request, comprising all characters up to the 
next SPACE.
       * Characters are tested by the supplied CharacterValidator, and an exception is 
thrown
       * if invalid characters are encountered.
       */
      protected String consumeWord( ImapRequestLineReader request,
                                    CharacterValidator validator )
              throws ProtocolException
      {
          StringBuffer atom = new StringBuffer();
  
          char next = request.nextWordChar();
          while( ! isWhitespace( next ) ) {
              if ( validator.isValid( next ) )
              {
                  atom.append( next );
                  request.consume();
              }
              else {
                  throw new ProtocolException( "Invalid character: '" + next + "'" );
              }
              next = request.nextChar();
          }
          return atom.toString();
      }
  
      private boolean isWhitespace( char next )
      {
          return ( next == ' ' || next == '\n' || next == '\r' || next == '\t' );
      }
  
      /**
       * Reads an argument of type "literal" from the request, in the format:
       *      "{" charCount "}" CRLF *CHAR8
       */
      protected String consumeLiteral( ImapRequestLineReader request )
              throws ProtocolException
      {
          // The 1st character must be '{'
          consumeChar( request, '{' );
  
          StringBuffer digits = new StringBuffer();
          char next = request.nextChar();
          while ( next != '}' )
          {
              digits.append( next );
              request.consume();
              next = request.nextChar();
          }
          // Consume the '}' and the newline
          consumeChar( request, '}' );
          endLine( request );
  
          int size = Integer.parseInt( digits.toString() );
          char[] buffer = new char[size];
          request.read( buffer );
  
          return new String( buffer );
      }
  
      /**
       * Consumes the next character in the request, checking that it matches the
       * expected one. This method should be used when the
       */
      protected void consumeChar( ImapRequestLineReader request, char expected )
              throws ProtocolException
      {
          char consumed = request.consume();
          Assert.isTrue( Assert.ON && consumed == expected );
      }
  
      /**
       * Reads a quoted string value from the request.
       */
      protected String consumeQuoted( ImapRequestLineReader request )
              throws ProtocolException
      {
          // The 1st character must be '"'
          consumeChar(request, '"' );
  
          StringBuffer quoted = new StringBuffer();
          char next = request.nextChar();
          while( next != '"' ) {
              if ( next == '\\' ) {
                  request.consume();
                  next = request.nextChar();
                  if ( ! isQuotedSpecial( next ) ) {
                      throw new ProtocolException( "Invalid escaped character in 
quote: '" +
                                                   next + "'" );
                  }
              }
              quoted.append( next );
              request.consume();
              next = request.nextChar();
          }
  
          consumeChar( request, '"' );
  
          return quoted.toString();
      }
  
      /**
       * Reads a base64 argument from the request.
       */
      public byte[] base64( ImapRequestLineReader request ) throws ProtocolException
      {
          return null;
      }
  
      /**
       * Reads a "flags" argument from the request.
       */
      public MessageFlags flagList( ImapRequestLineReader request )
      {
          // TODO implement
          return null;
      }
  
      /**
       * Reads an argument of type "number" from the request.
       */
      public long number( ImapRequestLineReader request ) throws ProtocolException
      {
          String digits = consumeWord( request, new DigitCharValidator() );
          return Long.parseLong( digits );
      }
  
      /**
       * Reads an argument of type "nznumber" (a non-zero number)
       * (NOTE this isn't strictly as per the spec, since the spec disallows
       * numbers such as "0123" as nzNumbers (although it's ok as a "number".
       * I think the spec is a bit shonky.)
       */
      public long nzNumber( ImapRequestLineReader request ) throws ProtocolException
      {
          long number = number( request );
          if ( number == 0 ) {
              throw new ProtocolException( "Zero value not permitted." );
          }
          return number;
      }
  
      private boolean isCHAR( char chr )
      {
          return ( chr >= 0x01 && chr <= 0x7f );
      }
  
      private boolean isCHAR8( char chr )
      {
          return ( chr >= 0x01 && chr <= 0xff );
      }
  
      protected boolean isListWildcard( char chr )
      {
          return ( chr == '*' || chr == '%' );
      }
  
      private boolean isQuotedSpecial( char chr )
      {
          return ( chr == '"' || chr == '\\' );
      }
  
      /**
       * Consumes the request up to and including the eno-of-line.
       * @param request The request
       * @throws ProtocolException If characters are encountered before the endLine.
       */
      public void endLine( ImapRequestLineReader request ) throws ProtocolException
      {
          request.eol();
      }
  
      /**
       * Provides the ability to ensure characters are part of a permitted set.
       */
      protected interface CharacterValidator
      {
          /**
           * Validates the supplied character.
           * @param chr The character to validate.
           * @return <code>true</code> if chr is valid, <code>false</code> if not.
           */
          boolean isValid( char chr );
      }
  
      protected class ATOM_CHARValidator implements CharacterValidator
      {
          public boolean isValid( char chr )
          {
              return ( isCHAR( chr ) && !isAtomSpecial( chr ) &&
                       !isListWildcard( chr ) && !isQuotedSpecial( chr ) );
          }
  
          private boolean isAtomSpecial( char chr )
          {
              return ( chr == '(' ||
                      chr == ')' ||
                      chr == '{' ||
                      chr == ' ' ||
                      chr == Character.CONTROL );
          }
      }
  
      protected class DigitCharValidator implements CharacterValidator
      {
          public boolean isValid( char chr )
          {
              return ( chr >= '0' && chr <= '9' );
          }
      }
  
      private class TagCharValidator extends ATOM_CHARValidator
      {
          public boolean isValid( char chr )
          {
              if ( chr == '+' ) return false;
              return super.isValid( chr );
          }
      }
  
  
  }
  
  
  
  1.1                  
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/commands/StatusCommand.java
  
  Index: StatusCommand.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  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.store.ImapMailbox;
  import org.apache.james.imapserver.store.MailboxException;
  
  /**
   * Handles processeing for the NOOP imap command.
   *
   * @author  Darrell DeBoer <[EMAIL PROTECTED]>
   *
   * @version $Revision: 1.1 $
   */
  class StatusCommand extends CommandTemplate
  {
      public static final String NAME = "STATUS";
      public static final String ARGS = "<mailbox> ( <status-data-item>+ )";
  
      private static final String MESSAGES = "MESSAGES";
      private static final String RECENT = "RECENT";
      private static final String UIDNEXT = "UIDNEXT";
      private static final String UIDVALIDITY = "UIDVALIDITY";
      private static final String UNSEEN = "UNSEEN";
  
      private StatusCommandParser parser = new StatusCommandParser();
  
      /** @see CommandTemplate#doProcess */
      protected void doProcess( ImapRequestLineReader request,
                                ImapResponse response,
                                ImapSession session )
              throws ProtocolException, MailboxException
      {
          String mailboxName = parser.astring( request );
          StatusDataItems statusDataItems = parser.statusDataItems( request );
          parser.endLine( request );
  
          ImapMailbox mailbox = getMailbox( mailboxName, session, true );
  
          StringBuffer buffer = new StringBuffer( mailboxName );
          buffer.append( SP );
          buffer.append( "(" );
  
          if ( statusDataItems.messages ) {
              buffer.append( MESSAGES );
              buffer.append( SP );
              buffer.append( mailbox.getMessageCount() );
              buffer.append( SP );
          }
  
          if ( statusDataItems.recent ) {
              buffer.append( RECENT );
              buffer.append( SP );
              buffer.append( mailbox.getRecentCount() );
              buffer.append( SP );
          }
  
          if ( statusDataItems.uidNext ) {
              buffer.append( UIDNEXT );
              buffer.append( SP );
              buffer.append( mailbox.getUidNext() );
              buffer.append( SP );
          }
  
          if ( statusDataItems.uidValidity ) {
              buffer.append( UIDVALIDITY );
              buffer.append( SP );
              buffer.append( mailbox.getUidValidity() );
              buffer.append( SP );
          }
  
          if ( statusDataItems.unseen ) {
              buffer.append( UNSEEN );
              buffer.append( SP );
              buffer.append( mailbox.getUnseenCount() );
              buffer.append( SP );
          }
  
          session.unsolicitedResponses( response );
          response.commandComplete( this );
      }
  
      /** @see ImapCommand#getName */
      public String getName()
      {
          return NAME;
      }
  
      /** @see CommandTemplate#getArgSyntax */
      public String getArgSyntax()
      {
          return ARGS;
      }
  
      private class StatusCommandParser extends CommandParser
      {
          StatusDataItems statusDataItems( ImapRequestLineReader request )
          {
              // TODO: implement.
              return new StatusDataItems();
          }
      }
  
      private class StatusDataItems
      {
          boolean messages;
          boolean recent;
          boolean uidNext;
          boolean uidValidity;
          boolean unseen;
      }
  }
  /*
  6.3.10. STATUS Command
  
     Arguments:  mailbox name
                 status data item names
  
     Responses:  untagged responses: STATUS
  
     Result:     OK - status completed
                 NO - status failure: no status for that name
                 BAD - command unknown or arguments invalid
  
        The STATUS command requests the status of the indicated mailbox.
        It does not change the currently selected mailbox, nor does it
        affect the state of any messages in the queried mailbox (in
        particular, STATUS MUST NOT cause messages to lose the \Recent
        flag).
  
        The STATUS command provides an alternative to opening a second
        IMAP4rev1 connection and doing an EXAMINE command on a mailbox to
        query that mailbox's status without deselecting the current
        mailbox in the first IMAP4rev1 connection.
  
        Unlike the LIST command, the STATUS command is not guaranteed to
        be fast in its response.  In some implementations, the server is
        obliged to open the mailbox read-only internally to obtain certain
        status information.  Also unlike the LIST command, the STATUS
        command does not accept wildcards.
  
        The currently defined status data items that can be requested are:
  
        MESSAGES       The number of messages in the mailbox.
  
        RECENT         The number of messages with the \Recent flag set.
  
        UIDNEXT        The next UID value that will be assigned to a new
                       message in the mailbox.  It is guaranteed that this
                       value will not change unless new messages are added
                       to the mailbox; and that it will change when new
                       messages are added even if those new messages are
                       subsequently expunged.
  
  
  
  Crispin                     Standards Track                    [Page 33]
  
  RFC 2060                       IMAP4rev1                   December 1996
  
  
        UIDVALIDITY    The unique identifier validity value of the
                       mailbox.
  
        UNSEEN         The number of messages which do not have the \Seen
                       flag set.
  
  
        Example:    C: A042 STATUS blurdybloop (UIDNEXT MESSAGES)
                    S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
                    S: A042 OK STATUS completed
  
  */
  
  
  
  1.2       +6 -1      
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/store/ImapMailbox.java
  
  Index: ImapMailbox.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/store/ImapMailbox.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ImapMailbox.java  22 Nov 2002 02:09:52 -0000      1.1
  +++ ImapMailbox.java  25 Nov 2002 01:11:44 -0000      1.2
  @@ -39,4 +39,9 @@
       int getIndex( int uid );
   
       boolean isSelectable();
  +
  +    int getUidNext();
  +
  +    int getUnseenCount();
  +    
   }
  
  
  
  1.2       +11 -1     
jakarta-james/proposals/imap2/java/org/apache/james/imapserver/store/InMemoryStore.java
  
  Index: InMemoryStore.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/java/org/apache/james/imapserver/store/InMemoryStore.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InMemoryStore.java        22 Nov 2002 02:09:52 -0000      1.1
  +++ InMemoryStore.java        25 Nov 2002 01:11:44 -0000      1.2
  @@ -248,6 +248,16 @@
               return 0;
           }
   
  +        public int getUidNext()
  +        {
  +            return 0;
  +        }
  +
  +        public int getUnseenCount()
  +        {
  +            return 0;
  +        }
  +
           public int getFirstUnseen()
           {
               return 0;
  
  
  
  1.2       +1 -1      
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Authenticate.test
  
  Index: Authenticate.test
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Authenticate.test,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Authenticate.test 22 Nov 2002 02:09:52 -0000      1.1
  +++ Authenticate.test 25 Nov 2002 01:11:45 -0000      1.2
  @@ -6,4 +6,4 @@
   S: abcd BAD Missing argument. Command should be '<tag> AUTHENTICATE <auth_type> 
\*\(CRLF base64\)'
   
   C: abcd AUTHENTICATE KERBEROS_V4 extra
  -S: abcd BAD Extra argument found. Command should be '<tag> AUTHENTICATE <auth_type> 
\*\(CRLF base64\)'
  +S: abcd BAD Expected end-of-line, found more characters. Command should be '<tag> 
AUTHENTICATE <auth_type> \*\(CRLF base64\)'
  
  
  
  1.2       +1 -1      
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Capability.test
  
  Index: Capability.test
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Capability.test,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Capability.test   22 Nov 2002 02:09:52 -0000      1.1
  +++ Capability.test   25 Nov 2002 01:11:45 -0000      1.2
  @@ -3,4 +3,4 @@
   S: abcd OK CAPABILITY completed
   
   C: abcd CAPABILITY extra stuff
  -S: abcd BAD Extra argument found. Command should be '<tag> CAPABILITY'
  \ No newline at end of file
  +S: abcd BAD Expected end-of-line, found more characters. Command should be '<tag> 
CAPABILITY'
  \ No newline at end of file
  
  
  
  1.2       +1 -1      
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Login.test
  
  Index: Login.test
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Login.test,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Login.test        22 Nov 2002 02:09:52 -0000      1.1
  +++ Login.test        25 Nov 2002 01:11:45 -0000      1.2
  @@ -6,7 +6,7 @@
   S: a002 BAD Missing argument. Command should be '<tag> LOGIN <userid> <password>'
   
   C: a002a LOGIN imapuser password extra
  -S: a002a BAD Extra argument found. Command should be '<tag> LOGIN <userid> 
<password>'
  +S: a002a BAD Expected end-of-line, found more characters. Command should be '<tag> 
LOGIN <userid> <password>'
   
   C: a003 LOGIN invaliduser password
   S: a003 NO LOGIN failed
  
  
  
  1.2       +1 -1      
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Logout.test
  
  Index: Logout.test
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/proposals/imap2/test/org/apache/james/imapserver/Logout.test,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Logout.test       22 Nov 2002 02:09:52 -0000      1.1
  +++ Logout.test       25 Nov 2002 01:11:45 -0000      1.2
  @@ -1,5 +1,5 @@
   C: a023 LOGOUT extra stuff
  -S: a023 BAD Extra argument found. Command should be '<tag> LOGOUT'
  +S: a023 BAD Expected end-of-line, found more characters. Command should be '<tag> 
LOGOUT'
   
   C: A023 LOGOUT
   S: \* BYE IMAP4rev1 Server logging out
  
  
  
  1.1                  
jakarta-james/proposals/imap2/test/org/apache/james/imapserver/CommandParserTest.java
  
  Index: CommandParserTest.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.imapserver;
  
  import org.apache.james.imapserver.commands.CommandParser;
  
  import junit.framework.TestCase;
  
  import java.io.StringReader;
  import java.io.BufferedReader;
  
  /**
   * Tests for the {@link ImapRequestLineReader}.
   * TODO: atom, literal, other (not yet implemented) arguments
   * @author  Darrell DeBoer <[EMAIL PROTECTED]>
   *
   * @version $Revision: 1.1 $
   */
  public class CommandParserTest
          extends TestCase
  {
      private CommandParser parser = new CommandParser();
  
      public CommandParserTest( String s )
      {
          super( s );
      }
  
      public void testTag() throws Exception
      {
          String testRequest = "a01 a.not.her not+ok";
          ImapRequestLineReader request = getRequest( testRequest );
  
          assertEquals( "a01", parser.tag( request ) );
          assertEquals( "a.not.her", parser.tag( request ) );
  
          try {
              String test = parser.tag( request );
              fail( "Tags may not contain the '+' character." );
          }
          catch ( ProtocolException e ) {}
      }
  
      /**
       * Tests handling of quoted strings.
       * TODO: illegal characters. illegal escapes
       */
      public void testQuoted() throws Exception
      {
          String testRequest = "\"word\" \"words with spaces\" \"\" " +
                  "\"esca\\\\ped \\\" chars\"";
          ImapRequestLineReader request = getRequest( testRequest );
  
          assertEquals( "word", parser.astring( request) );
          assertEquals( "words with spaces", parser.astring( request)  );
          assertEquals( "", parser.astring( request)  );
          assertEquals( "esca\\ped \" chars", parser.astring( request ) );
      }
  
      /**
       * Tests handling of "literal" arguments.
       * TODO: test this thoroughly
       */
      public void testLiteral() throws Exception
      {
          String test = "{24}\nThese \tare 24\ncharacters";
          ImapRequestLineReader request = getRequest(test );
  
          assertEquals( "These \tare 24\ncharacters", parser.astring( request ) );
      }
  
      /**
       * Test handling of astring arguments. More detailed tests for atom,
       * quoted and literal should be in specific argument tests.
       * TODO: add literal
       */
      public void testAstring() throws Exception
      {
          String testRequest = "atom at.om \"quoted\" \"\" {6}\n\"here\"";
          ImapRequestLineReader request = getRequest( testRequest );
  
          assertEquals( "atom", parser.astring( request ) );
          assertEquals( "at.om", parser.astring( request ));
          assertEquals( "quoted", parser.astring( request ));
          assertEquals( "", parser.astring( request ));
          assertEquals( "\"here\"", parser.astring( request ));
      }
  
      private ImapRequestLineReader getRequest( String testRequest )
      {
          BufferedReader reader = new BufferedReader( new StringReader( testRequest ) 
);
          ImapRequestLineReader request = new ImapRequestLineReader( reader );
          return request;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to