1 21 22 27 28 package com.sun.mail.iap; 29 30 import java.util.Vector ; 31 import java.util.Properties ; 32 import java.io.*; 33 import java.net.*; 34 import com.sun.mail.util.*; 35 36 42 43 public class Protocol { 44 protected String host; 45 private Socket socket; 46 protected boolean debug; 48 protected boolean quote; 49 protected PrintStream out; 50 51 private TraceInputStream traceInput; private ResponseInputStream input; 53 54 private TraceOutputStream traceOutput; private DataOutputStream output; 56 57 private int tagCounter = 0; 58 59 private Vector handlers = null; 61 private long timestamp; 62 63 protected static final byte[] CRLF = { (byte)'\r', (byte)'\n'}; 64 65 77 public Protocol(String host, int port, boolean debug, 78 PrintStream out, Properties props, String prefix, 79 boolean isSSL) throws IOException, ProtocolException { 80 this.host = host; 81 this.debug = debug; 82 this.out = out; 83 84 socket = SocketFetcher.getSocket(host, port, props, prefix, isSSL); 85 String s = props.getProperty("mail.debug.quote"); 86 quote = s != null && s.equalsIgnoreCase("true"); 87 88 initStreams(out); 89 90 processGreeting(readResponse()); 92 93 timestamp = System.currentTimeMillis(); 94 95 } 96 97 private void initStreams(PrintStream out) throws IOException { 98 traceInput = new TraceInputStream(socket.getInputStream(), out); 99 traceInput.setTrace(debug); 100 traceInput.setQuote(quote); 101 input = new ResponseInputStream(traceInput); 102 103 traceOutput = new TraceOutputStream(socket.getOutputStream(), out); 104 traceOutput.setTrace(debug); 105 traceOutput.setQuote(quote); 106 output = new DataOutputStream(new BufferedOutputStream(traceOutput)); 107 } 108 109 112 public Protocol(InputStream in, OutputStream out, boolean debug) 113 throws IOException { 114 this.host = "localhost"; 115 this.debug = debug; 116 this.quote = false; 117 this.out = System.out; 118 119 traceInput = new TraceInputStream(in, System.out); 121 traceInput.setTrace(debug); 122 traceInput.setQuote(quote); 123 input = new ResponseInputStream(traceInput); 124 125 traceOutput = new TraceOutputStream(out, System.out); 126 traceOutput.setTrace(debug); 127 traceOutput.setQuote(quote); 128 output = new DataOutputStream(new BufferedOutputStream(traceOutput)); 129 130 timestamp = System.currentTimeMillis(); 131 } 132 133 136 137 public long getTimestamp() { 138 return timestamp; 139 } 140 141 144 public synchronized void addResponseHandler(ResponseHandler h) { 145 if (handlers == null) 146 handlers = new Vector (); 147 handlers.addElement(h); 148 } 149 150 153 public synchronized void removeResponseHandler(ResponseHandler h) { 154 if (handlers != null) 155 handlers.removeElement(h); 156 } 157 158 161 public void notifyResponseHandlers(Response[] responses) { 162 if (handlers == null) 163 return; 164 165 for (int i = 0; i < responses.length; i++) { Response r = responses[i]; 167 168 if (r == null) 170 continue; 171 172 int size = handlers.size(); 173 if (size == 0) 174 return; 175 Object [] h = new Object [size]; 178 handlers.copyInto(h); 179 180 for (int j = 0; j < size; j++) 182 ((ResponseHandler)h[j]).handleResponse(r); 183 } 184 } 185 186 protected void processGreeting(Response r) throws ProtocolException { 187 if (r.isBYE()) 188 throw new ConnectionException(this, r); 189 } 190 191 194 protected ResponseInputStream getInputStream() { 195 return input; 196 } 197 198 201 protected OutputStream getOutputStream() { 202 return output; 203 } 204 205 209 protected boolean supportsNonSyncLiterals() { 210 return false; 211 } 212 213 public Response readResponse() 214 throws IOException, ProtocolException { 215 return new Response(this); 216 } 217 218 public String writeCommand(String command, Argument args) 219 throws IOException, ProtocolException { 220 String tag = "A" + Integer.toString(tagCounter++, 10); 222 output.writeBytes(tag + " " + command); 223 224 if (args != null) { 225 output.write(' '); 226 args.write(this); 227 } 228 229 output.write(CRLF); 230 output.flush(); 231 return tag; 232 } 233 234 243 public synchronized Response[] command(String command, Argument args) { 244 Vector v = new Vector (); 245 boolean done = false; 246 String tag = null; 247 Response r = null; 248 249 try { 251 tag = writeCommand(command, args); 252 } catch (LiteralException lex) { 253 v.addElement(lex.getResponse()); 254 done = true; 255 } catch (Exception ex) { 256 v.addElement(Response.byeResponse(ex)); 258 done = true; 259 } 260 261 while (!done) { 262 try { 263 r = readResponse(); 264 } catch (IOException ioex) { 265 r = Response.byeResponse(ioex); 267 } catch (ProtocolException pex) { 268 continue; } 270 271 v.addElement(r); 272 273 if (r.isBYE()) done = true; 275 276 if (r.isTagged() && r.getTag().equals(tag)) 278 done = true; 279 } 280 281 Response[] responses = new Response[v.size()]; 282 v.copyInto(responses); 283 timestamp = System.currentTimeMillis(); 284 return responses; 285 } 286 287 290 public void handleResult(Response response) throws ProtocolException { 291 if (response.isOK()) 292 return; 293 else if (response.isNO()) 294 throw new CommandFailedException(response); 295 else if (response.isBAD()) 296 throw new BadCommandException(response); 297 else if (response.isBYE()) { 298 disconnect(); 299 throw new ConnectionException(this, response); 300 } 301 } 302 303 307 public void simpleCommand(String cmd, Argument args) 308 throws ProtocolException { 309 Response[] r = command(cmd, args); 311 312 notifyResponseHandlers(r); 314 315 handleResult(r[r.length-1]); 317 } 318 319 324 public void startTLS(String cmd) throws IOException, ProtocolException { 325 simpleCommand(cmd, null); 326 socket = SocketFetcher.startTLS(socket); 327 initStreams(out); 328 } 329 330 333 protected synchronized void disconnect() { 334 if (socket != null) { 335 try { 336 socket.close(); 337 } catch (IOException e) { } 338 socket = null; 339 } 340 } 341 342 345 protected void finalize() throws Throwable { 346 super.finalize(); 347 disconnect(); 348 } 349 } 350 | Popular Tags |