1 21 22 package org.armedbear.j.mail; 23 24 import java.io.IOException ; 25 import java.io.OutputStreamWriter ; 26 import java.net.ConnectException ; 27 import java.net.Socket ; 28 import java.net.SocketException ; 29 import java.net.UnknownHostException ; 30 import java.util.StringTokenizer ; 31 import javax.swing.SwingUtilities ; 32 import org.armedbear.j.Debug; 33 import org.armedbear.j.Editor; 34 import org.armedbear.j.FastStringBuffer; 35 import org.armedbear.j.Log; 36 import org.armedbear.j.ProgressNotifier; 37 import org.armedbear.j.Property; 38 39 public final class NntpSession 40 { 41 private static final int DEFAULT_PORT = 119; 42 43 private String errorText; 44 private String host; 45 private int port; 46 private Socket socket; 47 private MailReader reader; 48 private OutputStreamWriter writer; 49 private String groupName; 50 private int count; 51 private int first; 52 private int last; 53 54 public static final boolean DEFAULT_ECHO = false; 55 56 private boolean echo = DEFAULT_ECHO; 57 58 private NntpSession(String host, int port) 59 { 60 this.host = host; 61 this.port = port; 62 } 63 64 public static NntpSession getSession() 65 { 66 return getSession(Editor.preferences().getStringProperty(Property.NEWS)); 67 } 68 69 public static NntpSession getSession(String host) 70 { 71 if (host == null || host.length() == 0) 72 return null; 73 74 return new NntpSession(host, DEFAULT_PORT); 75 } 76 77 public String getErrorText() 78 { 79 return errorText; 80 } 81 82 private void setErrorText(String s) 83 { 84 errorText = s; 85 } 86 87 public void setEcho(boolean b) 88 { 89 echo = b; 90 } 91 92 public String getHost() 93 { 94 return host; 95 } 96 97 public int getCount() 98 { 99 return count; 100 } 101 102 public int getFirst() 103 { 104 return first; 105 } 106 107 public int getLast() 108 { 109 return last; 110 } 111 112 public String getArticle(int articleNumber, ProgressNotifier progressNotifier) 113 { 114 if (socket == null) 115 return _getArticle(articleNumber, progressNotifier); 116 117 int timeout = 119 Editor.preferences().getIntegerProperty(Property.NNTP_READ_TIMEOUT); 120 try { 121 socket.setSoTimeout(timeout); 122 } 123 catch (SocketException e) { 124 Log.error(e); 125 } 126 String s = _getArticle(articleNumber, progressNotifier); 127 if (s != null) 128 return s; 129 if (progressNotifier != null && progressNotifier.cancelled()) 130 return null; 131 132 if (timeout > 0) { 133 Log.debug("reconnecting ..."); 134 disconnect(); 135 return _getArticle(articleNumber, progressNotifier); 136 } 137 138 return null; 139 } 140 141 private String _getArticle(int articleNumber, ProgressNotifier progressNotifier) 142 { 143 writeLine("ARTICLE ".concat(String.valueOf(articleNumber))); 144 String response = readLine(); 145 if (response == null) 146 return null; 147 if (!response.startsWith("220")) 148 return null; 149 echo = false; 150 if (progressNotifier != null) 151 progressNotifier.progressStart(); 152 FastStringBuffer sb = new FastStringBuffer(1024); 153 while (true) { 154 String s = readLine(); 155 if (s == null) 156 return null; 157 if (s.equals(".")) 158 break; 159 sb.append(s); 160 sb.append("\r\n"); 161 if (progressNotifier != null) { 162 progressNotifier.progress("Received ", sb.length(), 0); 163 if (progressNotifier.cancelled()) { 164 Log.debug("getArticle cancelled!!"); 165 abort(); 166 break; 167 } 168 } 169 } 170 if (progressNotifier != null) { 171 progressNotifier.progress("Received ", sb.length(), 0); 172 progressNotifier.progressStop(); 173 } 174 echo = DEFAULT_ECHO; 175 return sb.toString(); 176 } 177 178 public boolean connect() 179 { 180 boolean succeeded = false; 181 try { 182 socket = new Socket (host, port); 183 reader = new MailReader(socket.getInputStream()); 184 writer = 185 new OutputStreamWriter (socket.getOutputStream(), "ISO-8859-1"); 186 readLine(); 187 return true; 188 } 189 catch (ConnectException e) { 190 setErrorText("Connection refused"); 191 return false; 192 } 193 catch (UnknownHostException e) { 194 setErrorText("Unknown host " + host); 195 return false; 196 } 197 catch (IOException e) { 198 Log.error(e); 199 return false; 200 } 201 } 202 203 public boolean reconnect() 204 { 205 if (connect()) 206 if (selectGroup(groupName)) 207 return true; 208 209 return false; 210 } 211 212 public void disconnect() 213 { 214 if (socket != null) { 215 writeLine("QUIT"); 216 readLine(); 217 } 218 abort(); 219 } 220 221 public void abort() 222 { 223 if (socket != null) { 224 try { 225 socket.close(); 226 } 227 catch (IOException e) { 228 Log.error(e); 229 } 230 socket = null; 231 reader = null; 232 writer = null; 233 } 234 } 235 236 public boolean selectGroup(String groupName) 237 { 238 writeLine("GROUP " + groupName); 239 String response = readLine(); 240 if (response == null) 241 return false; 242 StringTokenizer st = new StringTokenizer (response); 243 String token = st.nextToken(); 244 if (!token.equals("211")) 245 return false; 246 count = Integer.parseInt(st.nextToken()); 247 first = Integer.parseInt(st.nextToken()); 248 last = Integer.parseInt(st.nextToken()); 249 this.groupName = groupName; 250 return true; 251 } 252 253 public String readLine() 254 { 255 if (reader == null) { 256 Debug.bug("readLine reader is null"); 257 return null; 258 } 259 try { 260 String s = reader.readLine(); 261 if (echo && s != null) 262 Log.debug("<== ".concat(s)); 263 return s; 264 } 265 catch (IOException e) { 266 Log.error(e); 267 return null; 268 } 269 } 270 271 public boolean writeLine(String s) 272 { 273 if (writer == null) 274 if (!reconnect()) 275 return false; 276 if (echo) 277 Log.debug("==> ".concat(s)); 278 try { 279 writer.write(s); 280 writer.write("\r\n"); 281 writer.flush(); 282 return true; 283 } 284 catch (Exception e) { 285 Log.error(e); 286 } 287 Log.debug("writeLine trying to reconnect..."); 289 if (connect()) { 290 if (selectGroup(groupName)) { 291 if (echo) 292 Log.debug("==> ".concat(s)); 293 try { 294 writer.write(s); 295 writer.write("\r\n"); 296 writer.flush(); 297 return true; 298 } 299 catch (IOException e) { 300 Log.error(e); 301 } 302 } 303 } 304 return false; 305 } 306 } 307 | Popular Tags |