1737 lines
58 KiB
Java
1737 lines
58 KiB
Java
/*
|
||
* The contents of this file are subject to the Netscape Public License
|
||
* Version 1.0 (the "License"); you may not use this file except in compliance
|
||
* with the License. You may obtain a copy of the License at
|
||
* http://www.mozilla.org/NPL/.
|
||
*
|
||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||
* for the specific language governing rights and limitations under the License.
|
||
*
|
||
* The Original Code is the Netscape Messaging Access SDK Version 3.5 code,
|
||
* released on or about June 15, 1998.
|
||
*
|
||
* The Initial Developer of the Original Code is Netscape Communications
|
||
* Corporation. Portions created by Netscape are Copyright (C) 1998 Netscape
|
||
* Communications Corporation. All Rights Reserved.
|
||
*
|
||
* Contributor(s): ______________________________________.
|
||
*/
|
||
|
||
/*
|
||
* Copyright (c) 1997 and 1998 Netscape Communications Corporation
|
||
* (http://home.netscape.com/misc/trademarks.html)
|
||
*/
|
||
|
||
package netscape.messaging.imap4;
|
||
|
||
import java.io.*;
|
||
import java.net.*;
|
||
import java.util.*;
|
||
import java.lang.reflect.*;
|
||
import netscape.messaging.IO;
|
||
|
||
/**
|
||
*The IMAP4Client exposes the IMAP4 client level API.
|
||
*The client uses this class for communicating with a
|
||
*server using the IMAP4 protocol.
|
||
*<p>The IMAP4Client class contains API calls that map
|
||
*directly to the client commands defined in RFC 2060,
|
||
*as well as other API calls that are necessary to establish
|
||
*and maintain an IMAP4 session.
|
||
*<p>For a list of the IMAP4 RFCs referenced in the
|
||
*Messaging Access SDK and their URLs,
|
||
*see "Where to Find More Information" in "About This Book."
|
||
*/
|
||
|
||
public class IMAP4Client
|
||
{
|
||
/**
|
||
* Creates an IMAP4_Client object.
|
||
* Default constructor for an IMAP4_Client object;
|
||
* takes an IMAP4 response sink as a parameter.
|
||
*@param in_sink Response sink that implements the IIMAP4Sink interface.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public IMAP4Client(IIMAP4Sink in_sink)
|
||
{
|
||
//Internal objects
|
||
m_IOHandler = new IO();
|
||
m_systemPreferences = new SystemPreferences();
|
||
m_systemPreferences.setIO(m_IOHandler);
|
||
m_pendingCommands = new Vector();
|
||
m_commandVector = new Vector();
|
||
m_firstResponse = true;
|
||
m_tagID = 0;
|
||
m_processBlock = new Integer(1);
|
||
|
||
//Parsing variables
|
||
m_sink = in_sink;
|
||
m_dispatcher = null;
|
||
m_serverResponse = new StringBuffer();
|
||
m_tokens = new StringBuffer[3];
|
||
m_parserArgs = new StringBuffer[1];
|
||
for(int i = 0; i < m_tokens.length; i++)
|
||
{
|
||
m_tokens[i] = new StringBuffer();
|
||
}
|
||
//Note: The hashtables are static so there is only one set of hashtables
|
||
//for n connections and are defined under data members
|
||
}
|
||
|
||
///////////////////////////////////////////////
|
||
//General Commands
|
||
|
||
/**
|
||
* Connects to the IMAP server in_IMAPHost using the default port (143).
|
||
*<p>To specify the connection port, use the
|
||
*form of connect that takes a port number.
|
||
* @param in_IMAPHost Name of the host server to connect to.
|
||
* @return Boolean true if successfully connected, false otherwise.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #connect
|
||
* @see #disconnect
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
* @see IIMAP4Sink#ok
|
||
*/
|
||
public synchronized boolean connect(String in_IMAPHost)
|
||
throws IOException
|
||
{
|
||
return connect(in_IMAPHost, m_systemPreferences.getPort());
|
||
}
|
||
|
||
/**
|
||
* Connects to the IMAP server in_IMAPHost through the specified port.
|
||
*<p>To use the default connection port, use the
|
||
*form of connect that takes only the server name.
|
||
* @param in_IMAPHost Name of the host server to connect to.
|
||
* @param in_portNumber Number of the port to connect to.
|
||
* @return Boolean value: true if successfully connected, false otherwise.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #disconnect
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
* @see IIMAP4Sink#ok
|
||
*/
|
||
public synchronized boolean connect(String in_IMAPHost, int in_portNumber)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_IMAPHost == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
|
||
//Establish the IMAP connection
|
||
m_IOHandler.connect(in_IMAPHost, in_portNumber);
|
||
m_IOHandler.setTimeout(m_systemPreferences.getTimeout());
|
||
m_dispatcher = new Dispatcher(m_IOHandler, m_sink, m_pendingCommands, m_systemPreferences);
|
||
m_pendingCommands.addElement(IGlobals.connect);
|
||
m_firstResponse = true;
|
||
m_tagID = 0;
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* Closes the socket connection with the server.
|
||
* Can be used to perform a high level "Cancel" while retrieving a message.
|
||
* <P>NOTE: Do not call processResponses() after this method.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #connect
|
||
* @see IIMAP4Sink#bye
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized void disconnect() throws IOException
|
||
{
|
||
m_IOHandler.disconnect();
|
||
m_pendingCommands.removeAllElements();
|
||
m_tagID = 0;
|
||
}
|
||
|
||
/**
|
||
* Processes the server responses for all API commands executed prior to
|
||
* the invocation of this command.
|
||
* Calls the appropriate functions on the response
|
||
* sink to relay the results back to the user.
|
||
* Checks for responses that are buffered at the socket.
|
||
* It then reads, parses, and pushes the data through the IIMAP4Sink.
|
||
* NOTE: Synchronized internally.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public void processResponses() throws IOException
|
||
{
|
||
synchronized (m_processBlock)
|
||
{
|
||
String l_responseType = null;
|
||
Method l_responseParser = null;
|
||
char l_tokenChar;
|
||
|
||
//Parse server response and route data through the appropriate
|
||
//methods in the response sink
|
||
while(!m_pendingCommands.isEmpty())
|
||
{
|
||
m_IOHandler.readLine(m_serverResponse);
|
||
|
||
//Special case for connect
|
||
if(m_firstResponse)
|
||
{
|
||
m_pendingCommands.removeElement(IGlobals.connect);
|
||
}
|
||
|
||
//Initialize the tokens array
|
||
for(int i = 0; i < m_tokens.length; i++)
|
||
{
|
||
m_tokens[i].setLength(0);
|
||
}
|
||
|
||
//Tokenize the server response
|
||
for(int i = 0, j = 0; i < m_serverResponse.length(); i++)
|
||
{
|
||
l_tokenChar = m_serverResponse.charAt(i);
|
||
if(l_tokenChar == ' ')
|
||
{
|
||
j++;
|
||
if(j >= m_tokens.length)
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
m_tokens[j].append(l_tokenChar);
|
||
}
|
||
|
||
//Parse the server response and dispatch to appropriate method on sink
|
||
try
|
||
{
|
||
l_responseType = resolveType(m_tokens);
|
||
if(l_responseType.equals(IGlobals.BYE))
|
||
{
|
||
m_pendingCommands.removeAllElements();
|
||
m_tagID = 0;
|
||
}
|
||
m_parserArgs[0] = m_serverResponse;
|
||
l_responseParser = (Method)m_responseMapper.get(l_responseType);
|
||
l_responseParser.invoke(m_dispatcher, m_parserArgs);
|
||
}
|
||
catch(InvocationTargetException e)
|
||
{
|
||
Throwable l_exception = e.getTargetException();
|
||
if(l_exception instanceof IMAP4ServerException)
|
||
{
|
||
throw (IMAP4ServerException)l_exception;
|
||
}
|
||
else if(l_exception instanceof IMAP4Exception)
|
||
{
|
||
throw (IMAP4Exception)l_exception;
|
||
}
|
||
l_exception.printStackTrace();
|
||
throw (new IOException(IGlobals.DispatcherError + " " + l_exception.getMessage()));
|
||
}
|
||
catch(IllegalAccessException e)
|
||
{
|
||
throw (new IOException(IGlobals.DispatcherError + " " + e.getMessage()));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sends the specified command to the IMAP4 server.
|
||
* Allows the developer to extend the default commands supplied
|
||
* through the SDK. Equivalent to writing the value of
|
||
* the in_command parameter directly to the socket.
|
||
* Do not prepend a tag to the command; this is added
|
||
* internally. The server response is pushed back through
|
||
* IIMAP4Sink.rawResponse().
|
||
*<p>Success does not indicate successful completion of the
|
||
* command, just that it has been invoked on the IMAP4 Server.
|
||
* Finding out if the command executed successfully requires
|
||
* using IMAP4Sink.rawResponse() to examine the returned data.
|
||
* @param in_command The command to send to the IMAP server.
|
||
* @return String The tag associated with the command;
|
||
* FALSE otherwise.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#rawResponse
|
||
* @see IIMAP4Sink#rawResponse
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String sendCommand(String in_command) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_command == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
|
||
m_commandVector.addElement(in_command);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Sends in_command to the IMAP server.
|
||
* Allows the developer to extend the default commands supplied
|
||
* through the SDK. Equivalent to writing the value of
|
||
* the in_command parameter directly to the socket.
|
||
* Do not prepend a tag to the command; this is added
|
||
* internally. The server response is pushed back through
|
||
* IIMAP4Sink.rawResponse().
|
||
*<p>Success does not indicate successful completion of the
|
||
* command, just that it has been invoked on the IMAP4 Server.
|
||
* Finding out if the command executed successfully requires
|
||
* using IMAP4Sink.rawResponse() to examine the returned data.
|
||
* @param in_command The command to send to the IMAP server
|
||
* @return String The tag associated with the command;
|
||
* FALSE otherwise.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#rawResponse
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
protected synchronized String sendCommand(Vector in_command) throws IOException
|
||
{
|
||
String l_tag = null;
|
||
|
||
//Prepend a tag id and send the command
|
||
m_tagID++;
|
||
l_tag = String.valueOf(m_tagID);
|
||
|
||
in_command.insertElementAt(IGlobals.Space, 0);
|
||
in_command.insertElementAt(l_tag, 0);
|
||
in_command.addElement(IGlobals.CarriageNewLine);
|
||
|
||
try
|
||
{
|
||
m_IOHandler.write(in_command);
|
||
m_IOHandler.flush();
|
||
|
||
m_pendingCommands.addElement(l_tag);
|
||
in_command.removeAllElements();
|
||
}
|
||
catch(IOException e)
|
||
{
|
||
in_command.removeAllElements();
|
||
throw e;
|
||
}
|
||
|
||
return l_tag;
|
||
}
|
||
|
||
/**
|
||
* Retrieves the system preferences.
|
||
* @return SystemPreferences Object representing the system preferences.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized SystemPreferences getSystemPreferences()
|
||
{
|
||
return m_systemPreferences;
|
||
}
|
||
|
||
/**
|
||
* Sets a new response sink to route the server responses to.
|
||
* @param in_sink New IMAP4 response sink to use.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #getResponseSink
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized void setResponseSink(IIMAP4Sink in_sink) throws IOException
|
||
{
|
||
synchronized (m_processBlock)
|
||
{
|
||
//Check parameters
|
||
if(in_sink == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
|
||
m_sink = in_sink;
|
||
m_dispatcher.setResponseSink(m_sink);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Retrieves the response sink.
|
||
* @return IIMAP4Sink Response sink to which to route server responses.
|
||
* @see #setResponseSink
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized IIMAP4Sink getResponseSink()
|
||
{
|
||
return m_sink;
|
||
}
|
||
|
||
////////////////////////////////////////////////////
|
||
//The non-authenticated state
|
||
|
||
/**
|
||
* Logs in to server with user name and password.
|
||
* Identifies the client to the server and carries the plain text password
|
||
* authenticating this user. Logs in the user after establishing a connection
|
||
* to the IMAP4 server, which passes the user
|
||
* password over the network in the clear.
|
||
* @param in_user The user name.
|
||
* @param in_password The password of this user.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #logout
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
* @see IIMAP4Sink#bye
|
||
*/
|
||
public synchronized String login(String in_user, String in_password) throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_user == null) || (in_password == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
|
||
m_commandVector.addElement(IGlobals.LOGIN);
|
||
m_commandVector.addElement(in_user);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_password);
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Informs the server that the client is done with the connection.
|
||
* Closes the connection and logs the user out.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #logout
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
* @see IIMAP4Sink#bye
|
||
*/
|
||
public synchronized String logout() throws IOException
|
||
{
|
||
//Ending session.. close connection
|
||
m_commandVector.addElement(IGlobals.LOGOUT);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Gets positive server response; does not affect IMAP4 session.
|
||
* <P>The server responds to commands with a "still here" response.
|
||
* Sending the noop method does nothing except force this server response.
|
||
* Can be used to maintain server connection, perhaps being issued
|
||
* at timed intervals to make sure that the server is still active.
|
||
* <p>Can be used to poll for mail or get new mail. Most servers look for
|
||
* new mail whenever they receive a command. This method does nothing
|
||
* in itself, so it is ideal for triggering this server action.
|
||
* <p>Resets the autologout timer inside the server; may change the
|
||
* number of messages in a mailbox (due to new mail).
|
||
* May change or update the status of messages in mailboxes.
|
||
* Not needed by applications that do something and disconnect at once.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#noop
|
||
* @see IIMAP4Sink#exists
|
||
* @see IIMAP4Sink#expunge
|
||
* @see IIMAP4Sink#recent
|
||
* @see IIMAP4Sink#fetchStart
|
||
* @see IIMAP4Sink#fetchFlags
|
||
* @see IIMAP4Sink#fetchEnd
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String noop() throws IOException
|
||
{
|
||
m_commandVector.addElement(IGlobals.NOOP);
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Requests a listing of capabilities that the server supports.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #connect
|
||
* @see IIMAP4Sink#capability
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String capability() throws IOException
|
||
{
|
||
m_commandVector.addElement(IGlobals.CAPABILITY);
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
////////////////////////////////////////////////////
|
||
//The authenticated state
|
||
|
||
/**
|
||
* Appends the literal argument as a new message to the end of the
|
||
* specified destination mailbox.
|
||
* @param in_mailbox Mailbox name.
|
||
* @param in_optFlags Parenthesized list of optional flags.
|
||
* @param in_optDateTime Optional date/time string.
|
||
* @param in_inputLiteralStream The message literal.
|
||
* @return String The command object and the (available) server response.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String append(String in_mailbox, String in_optFlags,
|
||
String in_optDateTime, InputStream in_inputLiteralStream)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_mailbox == null) || (in_inputLiteralStream == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
|
||
if(m_dispatcher == null)
|
||
{
|
||
throw new IOException(errNotConnected);
|
||
}
|
||
|
||
//Note: This is a command continuation request. The subsequent response
|
||
//to the server's request for the message data is handled in Dispatcher.plus
|
||
String l_flags = in_optFlags;
|
||
String l_dateTime = in_optDateTime;
|
||
int l_totalSize = in_inputLiteralStream.available();
|
||
|
||
//Format the optional parameters
|
||
if(l_flags != null)
|
||
{
|
||
formatOptionalParam(l_flags);
|
||
}
|
||
else
|
||
{
|
||
l_flags = IGlobals.EmptyString;
|
||
}
|
||
|
||
if(l_dateTime != null)
|
||
{
|
||
formatOptionalParam(l_dateTime);
|
||
}
|
||
else
|
||
{
|
||
l_dateTime = IGlobals.EmptyString;
|
||
}
|
||
|
||
//Pass the input stream to the dispatcher
|
||
m_dispatcher.setAppendStream(in_inputLiteralStream);
|
||
|
||
//Issue the command
|
||
m_commandVector.addElement(IGlobals.APPEND);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(l_flags);
|
||
m_commandVector.addElement(l_dateTime);
|
||
m_commandVector.addElement(IGlobals.LCurly);
|
||
m_commandVector.addElement(String.valueOf(l_totalSize));
|
||
m_commandVector.addElement(IGlobals.RCurly);
|
||
|
||
try
|
||
{
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
catch(IOException e)
|
||
{
|
||
m_commandVector.removeAllElements();
|
||
throw e;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Creates a new mailbox with the given name.
|
||
* Be careful to use the correct separator character if you want to create
|
||
* a directory on the server side.
|
||
* You cannot and should not CREATE an INBOX.
|
||
* It is always there.
|
||
* @param in_mailbox Name of the mailbox to create.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String create(String in_mailbox) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.CREATE);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* PERMANENTLY removes the mailbox with the given name.
|
||
* You can not and should not DELETE the INBOX. The system needs it.
|
||
* @param in_mailbox Name of the mailbox to delete.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String delete(String in_mailbox) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.DELETE);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Selects a server mailbox for read-only access.
|
||
* @param in_mailbox Name of the mailbox to examine.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#flags
|
||
* @see IIMAP4Sink#exists
|
||
* @see IIMAP4Sink#recent
|
||
* @see IIMAP4Sink#ok
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String examine(String in_mailbox) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.EXAMINE);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Lists a subset of all names available
|
||
* to the client.
|
||
* @param in_refName String with reference name (prefix).
|
||
* @param in_mailbox String with mailbox name (suffix).
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#list
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String list(String in_refName, String in_mailbox)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_refName == null) || (in_mailbox == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.LIST);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_refName);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Return a subset of all names that the user has
|
||
* declared as being "active" or "subscribed".
|
||
* @param in_refName Reference name.
|
||
* @param in_mailbox Mailbox name with possible wildcards.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#lsub
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String lsub(String in_refName, String in_mailbox)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_refName == null) || (in_mailbox == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.LSUB);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_refName);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Renames a mailbox.
|
||
* @param in_currentMB String with the mailbox's current name.
|
||
* @param in_newMB String with the mailbox's new name.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String rename(String in_currentMB,String in_newMB)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_currentMB == null) || (in_newMB == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.RENAME);
|
||
m_commandVector.addElement(in_currentMB);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_newMB);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Selects a mailbox on the server.
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #examine
|
||
* @see IIMAP4Sink#flags
|
||
* @see IIMAP4Sink#exists
|
||
* @see IIMAP4Sink#recent
|
||
* @see IIMAP4Sink#ok
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String select(String in_mailbox) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.SELECT);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Requests the status of the specified mailbox.
|
||
* Requests one or more types of status, as specified by the data items parameter.
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @param in_statusData Status data items.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#statusMessages
|
||
* @see IIMAP4Sink#statusRecent
|
||
* @see IIMAP4Sink#statusUidnext
|
||
* @see IIMAP4Sink#statusUidvalidity
|
||
* @see IIMAP4Sink#statusUnseen
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String status(String in_mailbox, String in_statusData)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_mailbox == null) || (in_statusData == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.STATUS);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_statusData);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Adds the specified mailbox name to the server's set of "active" or
|
||
* "subscribed" mailboxes.
|
||
* This list is accessed through the lsub method.
|
||
* @param in_mailbox Name of the mailbox to add.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #unsubscribe
|
||
* @see #lsub
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String subscribe(String in_mailbox)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.SUBSCRIBE);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Removes the specified mailbox name from the server's set of "active" or
|
||
* "subscribed" mailboxes.
|
||
* @param in_mailbox Name of the mailbox to remove.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #unsubscribe
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String unsubscribe(String in_mailbox)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
|
||
}
|
||
m_commandVector.addElement(IGlobals.UNSUBSCRIBE);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
////////////////////////////////////////////////////
|
||
//The selected state
|
||
|
||
|
||
/**
|
||
* Requests a checkpoint of the currently selected mailbox.
|
||
* Also flushes existing mailbox states to disk.
|
||
* Actual method behavior depends on server implementation.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String check() throws IOException
|
||
{
|
||
m_commandVector.addElement(IGlobals.CHECK);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Closes the mailbox.
|
||
* Also removes any messages marked with the \Deleted flag.
|
||
* The session moves to the mailbox that contained the closed mailbox.
|
||
* The expunge() method removes messages without closing.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #expunge
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String close() throws IOException
|
||
{
|
||
m_commandVector.addElement(IGlobals.CLOSE);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Copies the specified message(s) from the currently selected mailbox
|
||
* to the end of the specified destination mailbox.
|
||
* @param in_msgSet Message numbers to copy (for example, "1:2").
|
||
* @param in_mailbox Name of target mailbox.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #uidCopy
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String copy(String in_msgSet, String in_mailbox)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_msgSet == null) || (in_mailbox == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.COPY);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_msgSet);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Removes all messages flagged for deletion.
|
||
* Deletes all the messages in the
|
||
* mailbox with the \Deleted flag set. As described in RFC 1730, if there is
|
||
* an EXPUNGEd message, all messages with higher numbers are automatically
|
||
* decremented by one. This happens BEFORE this call returns,
|
||
* so, immediately following this call, you should think about
|
||
* what the state of the message cache might be.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#expunge
|
||
* @see #delete
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String expunge() throws IOException
|
||
{
|
||
m_commandVector.addElement(IGlobals.EXPUNGE);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Retrieves data specified by the fetch criteria for the given message
|
||
* set and returns the corresponding message sequence numbers.
|
||
* @param in_msgSet Message set.
|
||
* @param in_fetchCriteria Message data item names.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #uidFetch
|
||
* @see IIMAP4Sink#fetchStart
|
||
* @see IIMAP4Sink#fetchEnd
|
||
* @see IIMAP4Sink#fetchSize
|
||
* @see IIMAP4Sink#fetchData
|
||
* @see IIMAP4Sink#fetchFlags
|
||
* @see IIMAP4Sink#fetchBodyStructure
|
||
* @see IIMAP4Sink#fetchEnvelope
|
||
* @see IIMAP4Sink#fetchInternalDate
|
||
* @see IIMAP4Sink#fetchHeader
|
||
* @see IIMAP4Sink#fetchUid
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String fetch(String in_msgSet, String in_fetchCriteria)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_msgSet == null) || (in_fetchCriteria == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.FETCH);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_msgSet);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_fetchCriteria);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Searches the mailbox for messages that match the given search
|
||
* criteria.
|
||
* @param in_criteria Search criteria consisting of one or more search keys.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#search
|
||
* @see #uidSearch
|
||
* @see IIMAP4Sink#searchStart
|
||
* @see IIMAP4Sink#search
|
||
* @see IIMAP4Sink#searchEnd
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String search(String in_criteria)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_criteria == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.SEARCH);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_criteria);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Alters data associated with a message in the mailbox.
|
||
* @param in_msgSet Message set.
|
||
* @param in_dataItem Message data item name.
|
||
* @param in_value Value for the message data item.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #uidStore
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String store(String in_msgSet, String in_dataItem, String in_value)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_msgSet == null) || (in_dataItem == null) || (in_value == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.STORE);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_msgSet);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_dataItem);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_value);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Copies messages specified with a unique identifier.
|
||
* Performs a UID COPY.
|
||
* @param in_msgSet Message numbers to copy (for example, "1:2").
|
||
* @param in_mailbox Name of target mailbox.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #copy
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String uidCopy(String in_msgSet, String in_mailbox)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_msgSet == null) || (in_mailbox == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.UID);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(IGlobals.COPY);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_msgSet);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Fetches messages specified with a unique identifier
|
||
* and retrieve the corresponding unique identifiers.
|
||
* Performs a UID FETCH.
|
||
* @param in_msgSet The message set
|
||
* @param in_fetchCriteria The message data item names
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #fetch
|
||
* @see IIMAP4Sink#fetchStart
|
||
* @see IIMAP4Sink#fetchEnd
|
||
* @see IIMAP4Sink#fetchSize
|
||
* @see IIMAP4Sink#fetchData
|
||
* @see IIMAP4Sink#fetchFlags
|
||
* @see IIMAP4Sink#fetchBodyStructure
|
||
* @see IIMAP4Sink#fetchEnvelope
|
||
* @see IIMAP4Sink#fetchInternalDate
|
||
* @see IIMAP4Sink#fetchHeader
|
||
* @see IIMAP4Sink#fetchUid
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String uidFetch(String in_msgSet, String in_fetchCriteria)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_msgSet == null) || (in_fetchCriteria == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.UID);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(IGlobals.FETCH);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_msgSet);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_fetchCriteria);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
*
|
||
* Stores a message specified by a unique identifier.
|
||
* Performs a UID STORE.
|
||
* @param in_set Message set.
|
||
* @param in_dataItem Message data item name.
|
||
* @param in_value Value for the message data item.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #store
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String uidStore(String in_msgSet, String in_dataItem, String in_value)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_msgSet == null) || (in_dataItem == null) || (in_value == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.UID);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(IGlobals.STORE);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_msgSet);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_dataItem);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_value);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Searches the mailbox for messages that match the search criteria
|
||
* and retrieves the corresponding unique identifiers.
|
||
* Performs a UID SEARCH.
|
||
* @param in_criteria Search criteria consisting of one or more search keys.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #search
|
||
* @see IIMAP4Sink#searchStart
|
||
* @see IIMAP4Sink#search
|
||
* @see IIMAP4Sink#searchEnd
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String uidSearch(String in_criteria)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_criteria == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.UID);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(IGlobals.SEARCH);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_criteria);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
// Extended Commands
|
||
////////////////////////////////////////////////////////////////////
|
||
|
||
/**
|
||
* Retrieves the prefixes of namespaces used by a server for
|
||
* personal mailboxes, other user's mailboxes, and shared mailboxes.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see IIMAP4Sink#nameSpaceStart
|
||
* @see IIMAP4Sink#nameSpacePersonal
|
||
* @see IIMAP4Sink#nameSpaceOtherUsers
|
||
* @see IIMAP4Sink#nameSpaceShared
|
||
* @see IIMAP4Sink#nameSpaceEnd
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String nameSpace() throws IOException
|
||
{
|
||
m_commandVector.addElement(IGlobals.NAMESPACE);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Changes the access control list on the specified mailbox.
|
||
* The specified identifier is granted permissions specified in the
|
||
* third argument
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @param in_authId Authentication identifier.
|
||
* @param in_accessRight Access rights modification.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see deleteACL
|
||
* @see #getACL
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String setACL(String in_mailbox, String in_authId, String in_accessRight)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_mailbox == null) || (in_authId == null) || (in_accessRight == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.SETACL);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_authId);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_accessRight);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Removes an <identifier, rights> pair for the specified identifier
|
||
* from the access control list for the specified mailbox.
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @param in_authId Authentication identifier.
|
||
* @return String The tag associated with this command
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see setACL
|
||
* @see #getACL
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String deleteACL(String in_mailbox, String in_authId)
|
||
throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_mailbox == null) || (in_authId == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.DELETEACL);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_authId);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Retrieves the access control list for the mailbox in an untagged ACL reply.
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see deleteACL
|
||
* @see #setACL
|
||
* @see IIMAP4Sink#aclStart
|
||
* @see IIMAP4Sink#aclIdentifierRight
|
||
* @see IIMAP4Sink#aclEnd
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String getACL(String in_mailbox) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.GETACL);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Retrieves the access control list for mailbox in an untagged ACL reply.
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @param in_authId Authentication identifier.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #myRights
|
||
* @see IIMAP4Sink#listRightsStart
|
||
* @see IIMAP4Sink#listRightsRequiredRights
|
||
* @see IIMAP4Sink#listRightsOptionalRights
|
||
* @see IIMAP4Sink#listRightsEnd
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String listRights(String in_mailbox, String in_authId) throws IOException
|
||
{
|
||
//Check parameters
|
||
if((in_mailbox == null) || (in_authId == null))
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.LISTRIGHTS);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_authId);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
/**
|
||
* Retrieves the user<65>s rights to the specified mailbox.
|
||
* @param in_mailbox Name of the mailbox.
|
||
* @return String The tag associated with this command.
|
||
* @exception IOException If an I/O error occurs.
|
||
* @see #listRights
|
||
* @see IIMAP4Sink#myRights
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
public synchronized String myRights(String in_mailbox) throws IOException
|
||
{
|
||
//Check parameters
|
||
if(in_mailbox == null)
|
||
{
|
||
throw new IllegalArgumentException();
|
||
}
|
||
m_commandVector.addElement(IGlobals.MYRIGHTS);
|
||
m_commandVector.addElement(IGlobals.Space);
|
||
m_commandVector.addElement(in_mailbox);
|
||
|
||
return sendCommand(m_commandVector);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
// Internal Methods
|
||
////////////////////////////////////////////////////////////////////
|
||
|
||
/**
|
||
* Returns the token that represents the server response type.
|
||
* @param in_tokens The first 3 tokens in the current server response line
|
||
* @return StringBuffer The server response type or null if unknown type
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
private String resolveType(StringBuffer in_tokens[])
|
||
{
|
||
int l_token1Length = in_tokens[1].length();
|
||
int l_token2Length = in_tokens[2].length();
|
||
if((in_tokens[0].length() < 1) || (l_token1Length < 1))
|
||
{
|
||
return IGlobals.UNKNOWN;
|
||
}
|
||
|
||
if('*' == in_tokens[0].charAt(0))
|
||
{
|
||
switch(in_tokens[1].charAt(0))
|
||
{
|
||
case 'C':
|
||
{
|
||
if( (l_token1Length > 9) &&
|
||
(in_tokens[1].charAt(1) == 'A') &&
|
||
(in_tokens[1].charAt(2) == 'P') &&
|
||
(in_tokens[1].charAt(3) == 'A') &&
|
||
(in_tokens[1].charAt(4) == 'B') &&
|
||
(in_tokens[1].charAt(5) == 'I') &&
|
||
(in_tokens[1].charAt(6) == 'L') &&
|
||
(in_tokens[1].charAt(7) == 'I') &&
|
||
(in_tokens[1].charAt(8) == 'T') &&
|
||
(in_tokens[1].charAt(9) == 'Y'))
|
||
{
|
||
return IGlobals.CAPABILITY;
|
||
}
|
||
break;
|
||
}
|
||
case 'L':
|
||
{
|
||
if( (l_token1Length > 9) &&
|
||
(in_tokens[1].charAt(1) == 'I') &&
|
||
(in_tokens[1].charAt(2) == 'S') &&
|
||
(in_tokens[1].charAt(3) == 'T') &&
|
||
(in_tokens[1].charAt(4) == 'R') &&
|
||
(in_tokens[1].charAt(5) == 'I') &&
|
||
(in_tokens[1].charAt(6) == 'G') &&
|
||
(in_tokens[1].charAt(7) == 'H') &&
|
||
(in_tokens[1].charAt(8) == 'T') &&
|
||
(in_tokens[1].charAt(9) == 'S'))
|
||
{
|
||
return IGlobals.LISTRIGHTS;
|
||
}
|
||
else if( (l_token1Length > 3) &&
|
||
(in_tokens[1].charAt(1) == 'I') &&
|
||
(in_tokens[1].charAt(2) == 'S') &&
|
||
(in_tokens[1].charAt(3) == 'T'))
|
||
{
|
||
return IGlobals.LIST;
|
||
}
|
||
else if((l_token1Length > 3) &&
|
||
(in_tokens[1].charAt(1) == 'S') &&
|
||
(in_tokens[1].charAt(2) == 'U') &&
|
||
(in_tokens[1].charAt(3) == 'B'))
|
||
{
|
||
return IGlobals.LSUB;
|
||
}
|
||
break;
|
||
}
|
||
case 'S':
|
||
{
|
||
if( (l_token1Length > 5) &&
|
||
(in_tokens[1].charAt(1) == 'T') &&
|
||
(in_tokens[1].charAt(2) == 'A') &&
|
||
(in_tokens[1].charAt(3) == 'T') &&
|
||
(in_tokens[1].charAt(4) == 'U') &&
|
||
(in_tokens[1].charAt(5) == 'S'))
|
||
{
|
||
return IGlobals.STATUS;
|
||
}
|
||
else if((l_token1Length > 5) &&
|
||
(in_tokens[1].charAt(1) == 'E') &&
|
||
(in_tokens[1].charAt(2) == 'A') &&
|
||
(in_tokens[1].charAt(3) == 'R') &&
|
||
(in_tokens[1].charAt(4) == 'C') &&
|
||
(in_tokens[1].charAt(5) == 'H'))
|
||
{
|
||
return IGlobals.SEARCH;
|
||
}
|
||
break;
|
||
}
|
||
case 'F':
|
||
{
|
||
if( (l_token1Length > 4) &&
|
||
(in_tokens[1].charAt(1) == 'L') &&
|
||
(in_tokens[1].charAt(2) == 'A') &&
|
||
(in_tokens[1].charAt(3) == 'G') &&
|
||
(in_tokens[1].charAt(4) == 'S'))
|
||
{
|
||
return IGlobals.FLAGS;
|
||
}
|
||
break;
|
||
}
|
||
case 'O':
|
||
{
|
||
if( (l_token1Length > 1) &&
|
||
(in_tokens[1].charAt(1) == 'K'))
|
||
{
|
||
return IGlobals.OK;
|
||
}
|
||
break;
|
||
}
|
||
case 'N':
|
||
{
|
||
if( (l_token1Length > 1) &&
|
||
(in_tokens[1].charAt(1) == 'O'))
|
||
{
|
||
return IGlobals.NO;
|
||
}
|
||
else if( (l_token1Length > 8) &&
|
||
(in_tokens[1].charAt(1) == 'A') &&
|
||
(in_tokens[1].charAt(2) == 'M') &&
|
||
(in_tokens[1].charAt(3) == 'E') &&
|
||
(in_tokens[1].charAt(4) == 'S') &&
|
||
(in_tokens[1].charAt(5) == 'P') &&
|
||
(in_tokens[1].charAt(6) == 'A') &&
|
||
(in_tokens[1].charAt(7) == 'C') &&
|
||
(in_tokens[1].charAt(8) == 'E'))
|
||
{
|
||
return IGlobals.NAMESPACE;
|
||
}
|
||
break;
|
||
}
|
||
case 'P':
|
||
{
|
||
if( (l_token1Length > 6) &&
|
||
(in_tokens[1].charAt(1) == 'R') &&
|
||
(in_tokens[1].charAt(2) == 'E') &&
|
||
(in_tokens[1].charAt(3) == 'A') &&
|
||
(in_tokens[1].charAt(4) == 'U') &&
|
||
(in_tokens[1].charAt(5) == 'T') &&
|
||
(in_tokens[1].charAt(6) == 'H'))
|
||
{
|
||
return IGlobals.PREAUTH;
|
||
}
|
||
break;
|
||
}
|
||
case 'B':
|
||
{
|
||
if( (l_token1Length > 2) &&
|
||
(in_tokens[1].charAt(1) == 'Y') &&
|
||
(in_tokens[1].charAt(2) == 'E'))
|
||
{
|
||
return IGlobals.BYE;
|
||
}
|
||
else if((l_token1Length > 2) &&
|
||
(in_tokens[1].charAt(1) == 'A') &&
|
||
(in_tokens[1].charAt(2) == 'D'))
|
||
{
|
||
return IGlobals.BAD;
|
||
}
|
||
break;
|
||
}
|
||
case 'A':
|
||
{
|
||
if( (l_token1Length > 2) &&
|
||
(in_tokens[1].charAt(1) == 'C') &&
|
||
(in_tokens[1].charAt(2) == 'L'))
|
||
{
|
||
return IGlobals.ACL;
|
||
}
|
||
break;
|
||
}
|
||
case 'M':
|
||
{
|
||
if( (l_token1Length > 7) &&
|
||
(in_tokens[1].charAt(1) == 'Y') &&
|
||
(in_tokens[1].charAt(2) == 'R') &&
|
||
(in_tokens[1].charAt(3) == 'I') &&
|
||
(in_tokens[1].charAt(4) == 'G') &&
|
||
(in_tokens[1].charAt(5) == 'H') &&
|
||
(in_tokens[1].charAt(6) == 'T') &&
|
||
(in_tokens[1].charAt(7) == 'S'))
|
||
{
|
||
return IGlobals.MYRIGHTS;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
switch(in_tokens[2].charAt(0))
|
||
{
|
||
case 'R':
|
||
{
|
||
if( (l_token2Length > 5) &&
|
||
(in_tokens[2].charAt(1) == 'E') &&
|
||
(in_tokens[2].charAt(2) == 'C') &&
|
||
(in_tokens[2].charAt(3) == 'E') &&
|
||
(in_tokens[2].charAt(4) == 'N') &&
|
||
(in_tokens[2].charAt(5) == 'T'))
|
||
{
|
||
return IGlobals.RECENT;
|
||
}
|
||
break;
|
||
}
|
||
case 'E':
|
||
{
|
||
if( (l_token2Length > 5) &&
|
||
(in_tokens[2].charAt(1) == 'X') &&
|
||
(in_tokens[2].charAt(2) == 'I') &&
|
||
(in_tokens[2].charAt(3) == 'S') &&
|
||
(in_tokens[2].charAt(4) == 'T') &&
|
||
(in_tokens[2].charAt(5) == 'S'))
|
||
{
|
||
return IGlobals.EXISTS;
|
||
}
|
||
else if((l_token2Length > 6) &&
|
||
(in_tokens[2].charAt(1) == 'X') &&
|
||
(in_tokens[2].charAt(2) == 'P') &&
|
||
(in_tokens[2].charAt(3) == 'U') &&
|
||
(in_tokens[2].charAt(4) == 'N') &&
|
||
(in_tokens[2].charAt(5) == 'G') &&
|
||
(in_tokens[2].charAt(6) == 'E'))
|
||
{
|
||
return IGlobals.EXPUNGE;
|
||
}
|
||
break;
|
||
}
|
||
case 'F':
|
||
{
|
||
if( (l_token2Length > 4) &&
|
||
(in_tokens[2].charAt(1) == 'E') &&
|
||
(in_tokens[2].charAt(2) == 'T') &&
|
||
(in_tokens[2].charAt(3) == 'C') &&
|
||
(in_tokens[2].charAt(4) == 'H'))
|
||
{
|
||
return IGlobals.FETCH;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if('+' == in_tokens[0].charAt(0))
|
||
{
|
||
return IGlobals.PLUS;
|
||
}
|
||
else
|
||
{
|
||
//Check for valid tag
|
||
int l_tag = m_dispatcher.atoi(in_tokens[0], 0, in_tokens[0].length());
|
||
if((l_tag > 0) && (l_tag <= m_tagID))
|
||
{
|
||
switch(in_tokens[1].charAt(0))
|
||
{
|
||
case 'O':
|
||
{
|
||
if( (l_token1Length > 1) &&
|
||
(in_tokens[1].charAt(1) == 'K'))
|
||
{
|
||
return IGlobals.taggedOK;
|
||
}
|
||
break;
|
||
}
|
||
case 'N':
|
||
{
|
||
if( (l_token1Length > 1) &&
|
||
(in_tokens[1].charAt(1) == 'O'))
|
||
{
|
||
return IGlobals.taggedNO;
|
||
}
|
||
break;
|
||
}
|
||
case 'B':
|
||
{
|
||
if( (l_token1Length > 2) &&
|
||
(in_tokens[1].charAt(1) == 'A') &&
|
||
(in_tokens[1].charAt(2) == 'D'))
|
||
{
|
||
return IGlobals.taggedBAD;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return IGlobals.UNKNOWN;
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Format optional parameters for command string construction.
|
||
* @param out_optParam The optional parameter.
|
||
* @see IIMAP4Sink#taggedLine
|
||
* @see IIMAP4Sink#error
|
||
*/
|
||
private void formatOptionalParam(String out_optParam)
|
||
{
|
||
//Format the flag string
|
||
out_optParam.trim();
|
||
if(out_optParam.length() > 0)
|
||
{
|
||
out_optParam += IGlobals.Space;
|
||
}
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
//Data members
|
||
////////////////////////////////////////////////////////////////////////
|
||
|
||
/**A vector of strings representing the command*/
|
||
private Vector m_commandVector;
|
||
|
||
/**The IO object*/
|
||
private IO m_IOHandler;
|
||
|
||
/**Flags*/
|
||
private boolean m_firstResponse;
|
||
|
||
/**The system preferences*/
|
||
private SystemPreferences m_systemPreferences;
|
||
|
||
/** The tag id*/
|
||
private int m_tagID;
|
||
protected Vector m_pendingCommands;
|
||
|
||
/** Variables to assist the parsing of the server response */
|
||
private StringBuffer[] m_tokens;
|
||
private StringBuffer m_serverResponse;
|
||
private StringBuffer m_parserArgs[];
|
||
|
||
/** Used to synchronize processResponses block*/
|
||
private IIMAP4Sink m_sink;
|
||
private Integer m_processBlock;
|
||
|
||
|
||
public final static int ENVELOPE_DATE = 0;
|
||
public final static int ENVELOPE_SUBJECT = 1;
|
||
public final static int ENVELOPE_FROM = 2;
|
||
public final static int ENVELOPE_SENDER = 3;
|
||
public final static int ENVELOPE_REPLYTO = 4;
|
||
public final static int ENVELOPE_TO = 5;
|
||
public final static int ENVELOPE_CC = 6;
|
||
public final static int ENVELOPE_BCC = 7;
|
||
public final static int ENVELOPE_INREPLYTO = 8;
|
||
public final static int ENVELOPE_MESSAGEID = 9;
|
||
|
||
/** The dispatcher*/
|
||
private Dispatcher m_dispatcher;
|
||
|
||
/** String constants*/
|
||
protected final static String errNotConnected = new String("Must connect to server");
|
||
|
||
/** Hashtables for mapping of response types to appropriate sink methods*/
|
||
private static Hashtable m_responseMapper;
|
||
private static Class[] m_args = new Class[1];
|
||
|
||
static
|
||
{
|
||
try
|
||
{
|
||
//The hash tables
|
||
m_responseMapper = new Hashtable();
|
||
|
||
//Initialize arguments
|
||
m_args[0] = StringBuffer.class;
|
||
|
||
//Command completed methods
|
||
m_responseMapper.put(IGlobals.taggedOK, Dispatcher.class.getMethod("taggedLine", m_args));
|
||
m_responseMapper.put(IGlobals.taggedBAD, Dispatcher.class.getMethod("error", m_args));
|
||
m_responseMapper.put(IGlobals.taggedNO, Dispatcher.class.getMethod("error", m_args));
|
||
|
||
m_responseMapper.put(IGlobals.BAD, Dispatcher.class.getMethod("untaggedError", m_args));
|
||
m_responseMapper.put(IGlobals.NO, Dispatcher.class.getMethod("untaggedError", m_args));
|
||
|
||
m_responseMapper.put(IGlobals.OK, Dispatcher.class.getMethod("ok", m_args));
|
||
m_responseMapper.put(IGlobals.CAPABILITY, Dispatcher.class.getMethod("capability", m_args));
|
||
m_responseMapper.put(IGlobals.LIST, Dispatcher.class.getMethod("list", m_args));
|
||
m_responseMapper.put(IGlobals.LSUB, Dispatcher.class.getMethod("lsub", m_args));
|
||
m_responseMapper.put(IGlobals.STATUS, Dispatcher.class.getMethod("status", m_args));
|
||
m_responseMapper.put(IGlobals.SEARCH, Dispatcher.class.getMethod("search", m_args));
|
||
m_responseMapper.put(IGlobals.FLAGS, Dispatcher.class.getMethod("flags", m_args));
|
||
m_responseMapper.put(IGlobals.BYE, Dispatcher.class.getMethod("bye", m_args));
|
||
m_responseMapper.put(IGlobals.RECENT, Dispatcher.class.getMethod("recent", m_args));
|
||
m_responseMapper.put(IGlobals.EXISTS, Dispatcher.class.getMethod("exists", m_args));
|
||
m_responseMapper.put(IGlobals.EXPUNGE, Dispatcher.class.getMethod("expunge", m_args));
|
||
m_responseMapper.put(IGlobals.FETCH, Dispatcher.class.getMethod("fetch", m_args));
|
||
m_responseMapper.put(IGlobals.PLUS, Dispatcher.class.getMethod("plus", m_args));
|
||
m_responseMapper.put(IGlobals.NAMESPACE, Dispatcher.class.getMethod("namespace", m_args));
|
||
m_responseMapper.put(IGlobals.ACL, Dispatcher.class.getMethod("acl", m_args));
|
||
m_responseMapper.put(IGlobals.LISTRIGHTS, Dispatcher.class.getMethod("listrights", m_args));
|
||
m_responseMapper.put(IGlobals.MYRIGHTS, Dispatcher.class.getMethod("myrights", m_args));
|
||
m_responseMapper.put(IGlobals.UNKNOWN, Dispatcher.class.getMethod("rawResponse", m_args));
|
||
}
|
||
catch(NoSuchMethodException e)
|
||
{
|
||
System.out.println("Fatal error: can't load functions " + e.getMessage());
|
||
}
|
||
|
||
}
|
||
}
|