Constructors Summary |
---|
public Protocol(String host, int port, boolean debug, PrintStream out, Properties props, String prefix, boolean isSSL)Constructor.
Opens a connection to the given host at given port.
try {
this.host = host;
this.debug = debug;
this.out = out;
this.props = props;
this.prefix = prefix;
socket = SocketFetcher.getSocket(host, port, props, prefix, isSSL);
quote = PropUtil.getBooleanProperty(props,
"mail.debug.quote", false);
initStreams(out);
// Read server greeting
processGreeting(readResponse());
timestamp = System.currentTimeMillis();
connected = true; // must be last statement in constructor
} finally {
/*
* If we get here because an exception was thrown, we need
* to disconnect to avoid leaving a connected socket that
* no one will be able to use because this object was never
* completely constructed.
*/
if (!connected)
disconnect();
}
|
public Protocol(InputStream in, OutputStream out, boolean debug)Constructor for debugging.
this.host = "localhost";
this.debug = debug;
this.quote = false;
this.out = System.out;
// XXX - inlined initStreams, won't allow later startTLS
traceInput = new TraceInputStream(in, System.out);
traceInput.setTrace(debug);
traceInput.setQuote(quote);
input = new ResponseInputStream(traceInput);
traceOutput = new TraceOutputStream(out, System.out);
traceOutput.setTrace(debug);
traceOutput.setQuote(quote);
output = new DataOutputStream(new BufferedOutputStream(traceOutput));
timestamp = System.currentTimeMillis();
|
Methods Summary |
---|
public void | addResponseHandler(com.sun.mail.iap.ResponseHandler h)Adds a response handler.
handlers.addElement(h);
|
public synchronized com.sun.mail.iap.Response[] | command(java.lang.String command, com.sun.mail.iap.Argument args)Send a command to the server. Collect all responses until either
the corresponding command completion response or a BYE response
(indicating server failure). Return all the collected responses.
commandStart(command);
Vector v = new Vector();
boolean done = false;
String tag = null;
Response r = null;
// write the command
try {
tag = writeCommand(command, args);
} catch (LiteralException lex) {
v.addElement(lex.getResponse());
done = true;
} catch (Exception ex) {
// Convert this into a BYE response
v.addElement(Response.byeResponse(ex));
done = true;
}
while (!done) {
try {
r = readResponse();
} catch (IOException ioex) {
// convert this into a BYE response
r = Response.byeResponse(ioex);
} catch (ProtocolException pex) {
continue; // skip this response
}
v.addElement(r);
if (r.isBYE()) // shouldn't wait for command completion response
done = true;
// If this is a matching command completion response, we are done
if (r.isTagged() && r.getTag().equals(tag))
done = true;
}
Response[] responses = new Response[v.size()];
v.copyInto(responses);
timestamp = System.currentTimeMillis();
commandEnd();
return responses;
|
private void | commandEnd()
|
private void | commandStart(java.lang.String command)
|
protected synchronized void | disconnect()Disconnect.
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// ignore it
}
socket = null;
}
|
protected void | finalize()Finalizer.
super.finalize();
disconnect();
|
protected com.sun.mail.iap.ResponseInputStream | getInputStream()Return the Protocol's InputStream.
return input;
|
protected synchronized java.lang.String | getLocalHost()Get the name of the local host.
The property .localhost overrides .localaddress,
which overrides what InetAddress would tell us.
// get our hostname and cache it for future use
if (localHostName == null || localHostName.length() <= 0)
localHostName =
props.getProperty(prefix + ".localhost");
if (localHostName == null || localHostName.length() <= 0)
localHostName =
props.getProperty(prefix + ".localaddress");
try {
if (localHostName == null || localHostName.length() <= 0) {
InetAddress localHost = InetAddress.getLocalHost();
localHostName = localHost.getCanonicalHostName();
// if we can't get our name, use local address literal
if (localHostName == null)
// XXX - not correct for IPv6
localHostName = "[" + localHost.getHostAddress() + "]";
}
} catch (UnknownHostException uhex) {
}
// last chance, try to get our address from our socket
if (localHostName == null || localHostName.length() <= 0) {
if (socket != null && socket.isBound()) {
InetAddress localHost = socket.getLocalAddress();
localHostName = localHost.getCanonicalHostName();
// if we can't get our name, use local address literal
if (localHostName == null)
// XXX - not correct for IPv6
localHostName = "[" + localHost.getHostAddress() + "]";
}
}
return localHostName;
|
protected java.io.OutputStream | getOutputStream()Return the Protocol's OutputStream
return output;
|
protected com.sun.mail.iap.ByteArray | getResponseBuffer()Return a buffer to be used to read a response.
The default implementation returns null, which causes
a new buffer to be allocated for every response.
return null;
|
public long | getTimestamp()Returns the timestamp.
return timestamp;
|
public void | handleResult(com.sun.mail.iap.Response response)Convenience routine to handle OK, NO, BAD and BYE responses.
if (response.isOK())
return;
else if (response.isNO())
throw new CommandFailedException(response);
else if (response.isBAD())
throw new BadCommandException(response);
else if (response.isBYE()) {
disconnect();
throw new ConnectionException(this, response);
}
|
private void | initStreams(java.io.PrintStream out)
traceInput = new TraceInputStream(socket.getInputStream(), out);
traceInput.setTrace(debug);
traceInput.setQuote(quote);
input = new ResponseInputStream(traceInput);
traceOutput = new TraceOutputStream(socket.getOutputStream(), out);
traceOutput.setTrace(debug);
traceOutput.setQuote(quote);
output = new DataOutputStream(new BufferedOutputStream(traceOutput));
|
public void | notifyResponseHandlers(com.sun.mail.iap.Response[] responses)Notify response handlers
if (handlers.size() == 0)
return;
for (int i = 0; i < responses.length; i++) { // go thru responses
Response r = responses[i];
// skip responses that have already been handled
if (r == null)
continue;
// Need to copy handlers list because handlers can be removed
// when handling a response.
Object[] h = handlers.toArray();
// dispatch 'em
for (int j = 0; j < h.length; j++) {
if (h[j] != null)
((ResponseHandler)h[j]).handleResponse(r);
}
}
|
protected void | processGreeting(com.sun.mail.iap.Response r)
if (r.isBYE())
throw new ConnectionException(this, r);
|
public com.sun.mail.iap.Response | readResponse()
return new Response(this);
|
public void | removeResponseHandler(com.sun.mail.iap.ResponseHandler h)Removed the specified response handler.
handlers.removeElement(h);
|
public void | simpleCommand(java.lang.String cmd, com.sun.mail.iap.Argument args)Convenience routine to handle simple IAP commands
that do not have responses specific to that command.
// Issue command
Response[] r = command(cmd, args);
// dispatch untagged responses
notifyResponseHandlers(r);
// Handle result of this command
handleResult(r[r.length-1]);
|
public synchronized void | startTLS(java.lang.String cmd)Start TLS on the current connection.
cmd is the command to issue to start TLS negotiation.
If the command succeeds, we begin TLS negotiation.
simpleCommand(cmd, null);
socket = SocketFetcher.startTLS(socket, host, props, prefix);
initStreams(out);
|
protected synchronized boolean | supportsNonSyncLiterals()Returns whether this Protocol supports non-synchronizing literals
Default is false. Subclasses should override this if required
return false;
|
public java.lang.String | writeCommand(java.lang.String command, com.sun.mail.iap.Argument args)
// assert Thread.holdsLock(this);
// can't assert because it's called from constructor
String tag = "A" + Integer.toString(tagCounter++, 10); // unique tag
output.writeBytes(tag + " " + command);
if (args != null) {
output.write(' ");
args.write(this);
}
output.write(CRLF);
output.flush();
return tag;
|