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