1 22 23 package gnu.mail.providers.nntp; 24 25 import java.io.ByteArrayInputStream ; 26 import java.io.ByteArrayOutputStream ; 27 import java.io.IOException ; 28 import java.util.HashMap ; 29 import java.util.LinkedList ; 30 import java.util.List ; 31 import java.util.Map ; 32 33 import javax.mail.FetchProfile ; 34 import javax.mail.Flags ; 35 import javax.mail.Folder ; 36 import javax.mail.FolderNotFoundException ; 37 import javax.mail.IllegalWriteException ; 38 import javax.mail.Message ; 39 import javax.mail.MessageRemovedException ; 40 import javax.mail.MessagingException ; 41 import javax.mail.MethodNotSupportedException ; 42 import javax.mail.event.ConnectionEvent ; 43 44 import gnu.inet.nntp.ArticleResponse; 45 import gnu.inet.nntp.GroupResponse; 46 import gnu.inet.nntp.HeaderEntry; 47 import gnu.inet.nntp.HeaderIterator; 48 import gnu.inet.nntp.NNTPConstants; 49 import gnu.inet.nntp.StatusResponse; 50 51 57 public final class NNTPFolder 58 extends Folder 59 { 60 61 String name; 62 int first = -1; 63 int last = -1; 64 int count = -1; 65 boolean open; 66 67 Map articleCache; 69 NNTPFolder(NNTPStore store, String name) 70 { 71 super(store); 72 this.name = name; 73 } 74 75 78 public String getName() 79 { 80 return name; 81 } 82 83 86 public String getFullName() 87 { 88 return name; 89 } 90 91 95 public Folder getParent() 96 throws MessagingException 97 { 98 NNTPStore ns = (NNTPStore)store; 99 return ns.root; 100 } 101 102 106 public int getType() 107 throws MessagingException 108 { 109 return HOLDS_MESSAGES; 110 } 111 112 public boolean isOpen() 113 { 114 return open; 115 } 116 117 120 public int getMode() 121 { 122 return READ_ONLY; 123 } 124 125 128 public Flags getPermanentFlags() 129 { 130 NNTPStore ns = (NNTPStore)store; 131 return new Flags (ns.permanentFlags); 132 } 133 134 139 public void open(int mode) 140 throws MessagingException 141 { 142 if (open) 145 throw new IllegalStateException (); 146 try 147 { 148 NNTPStore ns = (NNTPStore)store; 149 synchronized (ns.connection) { 150 GroupResponse response = ns.connection.group(name); 151 count = response.count; 152 first = response.first; 153 last = response.last; 154 } 155 156 articleCache = new HashMap (1024); open = true; 158 notifyConnectionListeners(ConnectionEvent.OPENED); 159 } 160 catch (StatusResponse e) 161 { 162 if (e.getStatus()==NNTPConstants.NO_SUCH_GROUP) 163 throw new FolderNotFoundException (e.getMessage(), this); 164 else 165 throw new MessagingException (e.getMessage(), e); 166 } 167 catch (IOException e) 168 { 169 throw new MessagingException (e.getMessage(), e); 170 } 171 } 172 173 176 public void close(boolean expunge) 177 throws MessagingException 178 { 179 if (!open) 180 throw new IllegalStateException (); 181 182 articleCache = null; 183 open = false; 184 notifyConnectionListeners(ConnectionEvent.CLOSED); 185 } 186 187 190 public boolean exists() 191 throws MessagingException 192 { 193 try 194 { 195 NNTPStore ns = (NNTPStore)store; 196 synchronized (ns.connection) 197 { 198 GroupResponse response = ns.connection.group(name); 199 count = response.count; 200 first = response.first; 201 last = response.last; 202 } 203 return true; 204 } 205 catch (StatusResponse e) 206 { 207 if (e.getStatus()==NNTPConstants.NO_SUCH_GROUP) 208 return false; 209 else 210 throw new MessagingException (e.getMessage(), e); 211 } 212 catch (IOException e) 213 { 214 throw new MessagingException (e.getMessage(), e); 215 } 216 } 217 218 221 public boolean hasNewMessages() 222 throws MessagingException 223 { 224 try 225 { 226 NNTPStore ns = (NNTPStore)store; 227 boolean hasNew = false; 228 synchronized (ns.connection) 229 { 230 GroupResponse response = ns.connection.group(name); 231 if (response.last>last) 232 hasNew = true; 233 count = response.count; 234 first = response.first; 235 last = response.last; 236 } 237 return hasNew; 238 } 239 catch (StatusResponse e) 240 { 241 if (e.getStatus()==NNTPConstants.NO_SUCH_GROUP) 242 throw new FolderNotFoundException (e.getMessage(), this); 243 else 244 throw new MessagingException (e.getMessage(), e); 245 } 246 catch (IOException e) 247 { 248 throw new MessagingException (e.getMessage(), e); 249 } 250 } 251 252 255 public int getMessageCount() 256 throws MessagingException 257 { 258 return count; 259 } 260 261 266 public Message getMessage(int msgnum) 267 throws MessagingException 268 { 269 if (!open) 270 throw new IllegalStateException (); 271 272 Integer key = new Integer (msgnum); 274 NNTPMessage m = (NNTPMessage)articleCache.get(key); 275 if (m!=null) 276 return m; 277 278 try 279 { 280 NNTPStore ns = (NNTPStore)store; 281 synchronized (ns.connection) 282 { 283 GroupResponse gr = ns.connection.group(name); 285 first = gr.first; 286 last = gr.last; 287 count = gr.count; 288 m = getMessageImpl(msgnum); 290 articleCache.put(key, m); 292 return m; 293 } 294 } 295 catch (StatusResponse e) 296 { 297 switch (e.getStatus()) 298 { 299 case NNTPConstants.NO_ARTICLE_SELECTED: 300 case NNTPConstants.NO_SUCH_ARTICLE_NUMBER: 301 case NNTPConstants.NO_SUCH_ARTICLE: 302 throw new MessageRemovedException (e.getMessage()); 303 default: 304 throw new MessagingException (e.getMessage(), e); 305 } 306 } 307 catch (IOException e) 308 { 309 throw new MessagingException (e.getMessage(), e); 310 } 311 } 312 313 317 NNTPMessage getMessageImpl(int msgnum) 318 throws IOException 319 { 320 NNTPStore ns = (NNTPStore)store; 321 ArticleResponse response = ns.connection.stat(msgnum); 323 String messageId = response.messageId; 324 return new NNTPMessage(this, msgnum, messageId); 325 } 326 327 332 public Message [] getMessages() 333 throws MessagingException 334 { 335 NNTPStore ns = (NNTPStore)store; 336 List acc = new LinkedList (); 337 synchronized (ns.connection) 338 { 339 try 340 { 341 GroupResponse gr = ns.connection.group(name); 343 first = gr.first; 344 last = gr.last; 345 count = gr.count; 346 StringBuffer rb = new StringBuffer (); 348 rb.append(Integer.toString(first)); 349 rb.append('-'); 350 rb.append(Integer.toString(last)); 351 HeaderIterator i = ns.connection.xhdr("Message-ID", rb.toString()); 352 while (i.hasNext()) 353 { 354 HeaderEntry entry = i.nextHeaderEntry(); 355 Integer key = new Integer (entry.getArticleId()); 356 NNTPMessage m = (NNTPMessage)articleCache.get(key); 358 if (m==null) 359 { 360 int msgnum = key.intValue(); 361 String messageId = entry.getHeader(); 362 m = new NNTPMessage(this, msgnum, messageId); 363 articleCache.put(key, m); 365 } 366 acc.add(m); 367 } 368 } 369 catch (StatusResponse e) 370 { 371 for (int i=first; i<=last; i++) 374 { 375 Integer key = new Integer (i); 376 Message m = (NNTPMessage)articleCache.get(key); 378 if (m==null) 379 { 380 try 381 { 382 m = getMessageImpl(i); 383 articleCache.put(key, m); 385 acc.add(m); 386 } 387 catch (StatusResponse se) 388 { 389 switch (se.getStatus()) 390 { 391 case NNTPConstants.NO_ARTICLE_SELECTED: 392 case NNTPConstants.NO_SUCH_ARTICLE_NUMBER: 393 case NNTPConstants.NO_SUCH_ARTICLE: 394 break; default: 396 throw new MessagingException (se.getMessage(), se); 397 } 398 } 399 catch (IOException ie) 400 { 401 throw new MessagingException (ie.getMessage(), ie); 402 } 403 } 404 } 405 } 406 catch (IOException e) 407 { 408 throw new MessagingException (e.getMessage(), e); 409 } 410 } 411 int len = acc.size(); 412 Message [] messages = new Message [len]; 413 acc.toArray(messages); 414 return messages; 415 } 416 417 420 public void fetch(Message [] msgs, FetchProfile fp) 421 throws MessagingException 422 { 423 boolean head = fp.contains(FetchProfile.Item.ENVELOPE); 424 head = head || (fp.getHeaderNames().length>0); 425 boolean body = fp.contains(FetchProfile.Item.CONTENT_INFO); 426 int op = (head && body) ? 3 : head ? 2 : body ? 1 : 0; 427 try 428 { 429 NNTPStore ns = (NNTPStore)store; 430 for (int i=0; i<msgs.length; i++) 431 { 432 Message msg = msgs[i]; 433 if (msg==null || !(msg instanceof NNTPMessage)) 434 continue; 435 NNTPMessage message = (NNTPMessage)msg; 436 String messageId = message.getMessageId(); 437 438 ArticleResponse response = null; 439 synchronized (ns.connection) 440 { 441 switch (op) 442 { 443 case 3: response = ns.connection.article(messageId); 445 break; 446 case 2: response = ns.connection.head(messageId); 448 break; 449 case 1: response = ns.connection.body(messageId); 451 break; 452 } 453 ByteArrayOutputStream out = new ByteArrayOutputStream (); 454 byte[] buf = new byte[4096]; 455 for (int len = response.in.read(buf); 456 len>-1; 457 len = response.in.read(buf)) 458 out.write(buf, 0, len); 459 switch (op) 460 { 461 case 3: ByteArrayInputStream hbin = 463 new ByteArrayInputStream (out.toByteArray()); 464 message.updateHeaders(hbin); 465 int len = hbin.available(); 466 byte[] content = new byte[len]; 467 hbin.read(content); 468 message.updateContent(content); 469 break; 470 case 2: ByteArrayInputStream hin = 472 new ByteArrayInputStream (out.toByteArray()); 473 message.updateHeaders(hin); 474 break; 475 case 1: message.updateContent(out.toByteArray()); 477 break; 478 } 479 } 480 } 481 } 482 catch (StatusResponse e) 483 { 484 switch (e.getStatus()) 485 { 486 case NNTPConstants.NO_GROUP_SELECTED: 487 throw new IllegalStateException (e.getMessage()); 488 case NNTPConstants.NO_ARTICLE_SELECTED: 489 case NNTPConstants.NO_SUCH_ARTICLE_NUMBER: 490 case NNTPConstants.NO_SUCH_ARTICLE: 491 throw new MessageRemovedException (e.getMessage()); 492 default: 493 throw new MessagingException (e.getMessage(), e); 494 } 495 } 496 catch (IOException e) 497 { 498 throw new MessagingException (e.getMessage(), e); 499 } 500 } 501 502 504 508 public boolean isSubscribed() 509 { 510 NNTPStore ns = (NNTPStore)store; 511 return ns.newsrc.isSubscribed(name); 512 } 513 514 518 public void setSubscribed(boolean flag) 519 throws MessagingException 520 { 521 NNTPStore ns = (NNTPStore)store; 522 ns.newsrc.setSubscribed(name, flag); 523 } 524 525 boolean isSeen(int articleNumber) 526 { 527 NNTPStore ns = (NNTPStore)store; 528 return ns.newsrc.isSeen(name, articleNumber); 529 } 530 531 void setSeen(int articleNumber, boolean flag) 532 { 533 NNTPStore ns = (NNTPStore)store; 534 ns.newsrc.setSeen(name, articleNumber, flag); 535 } 536 537 539 542 public Folder getFolder(String name) 543 throws MessagingException 544 { 545 throw new MethodNotSupportedException (); 546 } 547 548 551 public Folder [] list(String pattern) 552 throws MessagingException 553 { 554 throw new MethodNotSupportedException (); 555 } 556 557 560 public Folder [] listSubscribed(String pattern) 561 throws MessagingException 562 { 563 return list(pattern); 564 } 565 566 569 public char getSeparator() 570 throws MessagingException 571 { 572 return '.'; 573 } 574 575 578 public boolean create(int type) 579 throws MessagingException 580 { 581 throw new MethodNotSupportedException (); 582 } 583 584 587 public boolean delete(boolean recurse) 588 throws MessagingException 589 { 590 throw new MethodNotSupportedException (); 591 } 592 593 596 public boolean renameTo(Folder folder) 597 throws MessagingException 598 { 599 throw new MethodNotSupportedException (); 600 } 601 602 605 public void appendMessages(Message [] messages) 606 throws MessagingException 607 { 608 throw new IllegalWriteException (); 609 } 610 611 614 public Message [] expunge() 615 throws MessagingException 616 { 617 throw new IllegalWriteException (); 618 } 619 620 } 621 | Popular Tags |