1 21 22 27 28 package com.sun.mail.imap; 29 30 import java.util.Vector ; 31 import java.util.StringTokenizer ; 32 import java.io.PrintStream ; 33 import java.io.IOException ; 34 import java.net.InetAddress ; 35 import java.net.UnknownHostException ; 36 37 import javax.mail.*; 38 import javax.mail.event.*; 39 40 import com.sun.mail.iap.*; 41 import com.sun.mail.imap.protocol.*; 42 43 66 119 120 public class IMAPStore extends Store 121 implements QuotaAwareStore, ResponseHandler { 122 123 private String name = "imap"; private int defaultPort = 143; private boolean isSSL = false; 127 private int port = -1; private int blksize = 1024 * 16; 132 private int statusCacheTimeout = 1000; 134 private int appendBufferSize = -1; 136 private String host; 138 private String user; 139 private String password; 140 private String proxyAuthUser; 141 private String authorizationID; 142 private String saslRealm; 143 144 private Namespaces namespaces; 145 146 private boolean disableAuthLogin = false; private boolean disableAuthPlain = false; private boolean enableStartTLS = false; private boolean enableSASL = false; private String [] saslMechanisms; 151 private boolean forcePasswordRefresh = false; 152 153 private boolean debug; 154 private PrintStream out; 156 158 static class ConnectionPool { 159 160 private Vector authenticatedConnections = new Vector (); 162 163 private Vector folders; 165 166 private boolean separateStoreConnection = false; 169 170 private long borrowedStoreConnections = 0; 172 173 private long clientTimeoutInterval = 45 * 1000; 176 private long serverTimeoutInterval = 30 *60 * 1000; 179 private long lastTimePruned; 182 183 private int poolSize = 1; 185 186 private long pruningInterval = 60000; 188 189 private boolean debug = false; 191 } 192 193 private ConnectionPool pool = new ConnectionPool(); 194 195 196 200 public IMAPStore(Session session, URLName url) { 201 this(session, url, "imap", 143, false); 202 } 203 204 207 protected IMAPStore(Session session, URLName url, 208 String name, int defaultPort, boolean isSSL) { 209 super(session, url); if (url != null) 211 name = url.getProtocol(); 212 this.name = name; 213 this.defaultPort = defaultPort; 214 this.isSSL = isSSL; 215 216 pool.lastTimePruned = System.currentTimeMillis(); 217 218 debug = session.getDebug(); 219 out = session.getDebugOut(); 220 if (out == null) out = System.out; 222 223 String s = session.getProperty( 224 "mail." + name + ".connectionpool.debug"); 225 226 if (s != null && s.equalsIgnoreCase("true")) 227 pool.debug = true; 228 229 s = session.getProperty("mail." + name + ".partialfetch"); 230 231 if (s != null && s.equalsIgnoreCase("false")) { 232 blksize = -1; if (debug) 235 out.println("DEBUG: mail.imap.partialfetch: false"); 236 } else { if ((s = session.getProperty("mail." + name +".fetchsize")) 238 != null) 239 blksize = Integer.parseInt(s); 241 if (debug) 242 out.println("DEBUG: mail.imap.fetchsize: " + blksize); 243 } 244 245 s = session.getProperty("mail." + name + ".statuscachetimeout"); 246 if (s != null) { 247 statusCacheTimeout = Integer.parseInt(s); 248 if (debug) 249 out.println("DEBUG: mail.imap.statuscachetimeout: " + 250 statusCacheTimeout); 251 } 252 s = session.getProperty("mail." + name + ".appendbuffersize"); 253 if (s != null) { 254 appendBufferSize = Integer.parseInt(s); 255 if (debug) 256 out.println("DEBUG: mail.imap.appendbuffersize: " + 257 appendBufferSize); 258 } 259 260 s = session.getProperty("mail." + name + ".connectionpoolsize"); 262 if (s != null) { 263 try { 264 int size = Integer.parseInt(s); 265 if (size > 0) 266 pool.poolSize = size; 267 } catch (NumberFormatException nfe) { 268 } 269 if (pool.debug) 270 out.println("DEBUG: mail.imap.connectionpoolsize: " + 271 pool.poolSize); 272 } 273 274 275 s = session.getProperty("mail." + name + ".connectionpooltimeout"); 277 if (s != null) { 278 try { 279 int connectionPoolTimeout = Integer.parseInt(s); 280 if (connectionPoolTimeout > 0) 281 pool.clientTimeoutInterval = connectionPoolTimeout; 282 } catch (NumberFormatException nfe) { 283 } 284 if (pool.debug) 285 out.println("DEBUG: mail.imap.connectionpooltimeout: " + 286 pool.clientTimeoutInterval); 287 } 288 289 s = session.getProperty("mail." + name + ".servertimeout"); 291 if (s != null) { 292 try { 293 int serverTimeout = Integer.parseInt(s); 294 if (serverTimeout > 0) 295 pool.serverTimeoutInterval = serverTimeout; 296 } catch (NumberFormatException nfe) { 297 } 298 if (pool.debug) 299 out.println("DEBUG: mail.imap.servertimeout: " + 300 pool.serverTimeoutInterval); 301 } 302 303 s = session.getProperty("mail." + name + ".separatestoreconnection"); 306 if (s != null && s.equalsIgnoreCase("true")) { 307 if (pool.debug) 308 out.println("DEBUG: dedicate a store connection"); 309 pool.separateStoreConnection = true; 310 } 311 312 s = session.getProperty("mail." + name + ".proxyauth.user"); 314 if (s != null) { 315 proxyAuthUser = s; 316 if (debug) 317 out.println("DEBUG: mail.imap.proxyauth.user: " + 318 proxyAuthUser); 319 } 320 321 s = session.getProperty("mail." + name + ".auth.login.disable"); 323 if (s != null && s.equalsIgnoreCase("true")) { 324 if (debug) 325 out.println("DEBUG: disable AUTH=LOGIN"); 326 disableAuthLogin = true; 327 } 328 329 s = session.getProperty("mail." + name + ".auth.plain.disable"); 331 if (s != null && s.equalsIgnoreCase("true")) { 332 if (debug) 333 out.println("DEBUG: disable AUTH=PLAIN"); 334 disableAuthPlain = true; 335 } 336 337 s = session.getProperty("mail." + name + ".starttls.enable"); 339 if (s != null && s.equalsIgnoreCase("true")) { 340 if (debug) 341 out.println("DEBUG: enable STARTTLS"); 342 enableStartTLS = true; 343 } 344 345 s = session.getProperty("mail." + name + ".sasl.enable"); 347 if (s != null && s.equalsIgnoreCase("true")) { 348 if (debug) 349 out.println("DEBUG: enable SASL"); 350 enableSASL = true; 351 } 352 353 if (enableSASL) { 355 s = session.getProperty("mail." + name + ".sasl.mechanisms"); 356 if (s != null && s.length() > 0) { 357 if (debug) 358 out.println("DEBUG: SASL mechanisms allowed: " + s); 359 Vector v = new Vector (5); 360 StringTokenizer st = new StringTokenizer (s, " ,"); 361 while (st.hasMoreTokens()) { 362 String m = st.nextToken(); 363 if (m.length() > 0) 364 v.addElement(m); 365 } 366 saslMechanisms = new String [v.size()]; 367 v.copyInto(saslMechanisms); 368 } 369 } 370 371 s = session.getProperty("mail." + name + ".sasl.authorizationid"); 373 if (s != null) { 374 authorizationID = s; 375 if (debug) 376 out.println("DEBUG: mail.imap.sasl.authorizationid: " + 377 authorizationID); 378 } 379 380 s = session.getProperty("mail." + name + ".sasl.realm"); 382 if (s != null) { 383 saslRealm = s; 384 if (debug) 385 out.println("DEBUG: mail.imap.sasl.realm: " + saslRealm); 386 } 387 388 s = session.getProperty("mail." + name + ".forcepasswordrefresh"); 390 if (s != null && s.equalsIgnoreCase("true")) { 391 if (debug) 392 out.println("DEBUG: enable forcePasswordRefresh"); 393 forcePasswordRefresh = true; 394 } 395 } 396 397 407 protected synchronized boolean 408 protocolConnect(String host, int pport, String user, String password) 409 throws MessagingException { 410 411 IMAPProtocol protocol = null; 412 413 if (host == null || password == null || user == null) { 415 if (debug) 416 out.println("DEBUG: protocolConnect returning false" + 417 ", host=" + host + 418 ", user=" + user + 419 ", password=" + (password != null ? 420 "<non-null>" : "<null>")); 421 return false; 422 } 423 424 if (pport != -1) { 426 port = pport; 427 } else { 428 String portstring = session.getProperty("mail."+name+".port"); 429 if (portstring != null) { 430 port = Integer.parseInt(portstring); 431 } 432 } 433 434 if (port == -1) { 436 port = defaultPort; 437 } 438 439 try { 440 boolean poolEmpty; 441 synchronized (pool) { 442 poolEmpty = pool.authenticatedConnections.isEmpty(); 443 } 444 445 if (poolEmpty) { 446 protocol = new IMAPProtocol(name, host, port, 447 session.getDebug(), 448 session.getDebugOut(), 449 session.getProperties(), 450 isSSL 451 ); 452 if (debug) 453 out.println("DEBUG: protocolConnect login" + 454 ", host=" + host + 455 ", user=" + user + 456 ", password=" + (password != null ? 457 "<non-null>" : "<null>")); 458 login(protocol, user, password); 459 460 protocol.addResponseHandler(this); 461 462 this.host = host; 463 this.user = user; 464 this.password = password; 465 466 synchronized (pool) { 467 pool.authenticatedConnections.addElement(protocol); 468 } 469 } 470 } catch (CommandFailedException cex) { 471 protocol.disconnect(); 473 protocol = null; 474 throw new AuthenticationFailedException( 475 cex.getResponse().getRest()); 476 } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); 478 } catch (IOException ioex) { 479 throw new MessagingException(ioex.getMessage(), ioex); 480 } 481 482 return true; 483 484 } 485 486 private void login(IMAPProtocol p, String u, String pw) 487 throws ProtocolException { 488 if (enableStartTLS && p.hasCapability("STARTTLS")) { 490 p.startTLS(); 491 p.capability(); 493 } 494 if (p.isAuthenticated()) 495 return; String authzid; 497 if (authorizationID != null) 498 authzid = authorizationID; 499 else if (proxyAuthUser != null) 500 authzid = proxyAuthUser; 501 else 502 authzid = u; 503 if (enableSASL) { 504 p.sasllogin(saslMechanisms, saslRealm, authzid, u, pw); 505 if (p.isAuthenticated()) { 506 if (proxyAuthUser != null) 507 p.proxyauth(proxyAuthUser); 508 return; 509 } 510 } 511 if (p.hasCapability("AUTH=PLAIN") && !disableAuthPlain) 512 p.authplain(authzid, u, pw); 513 else if ((p.hasCapability("AUTH-LOGIN") || 514 p.hasCapability("AUTH=LOGIN")) && !disableAuthLogin) 515 p.authlogin(u, pw); 516 else if (!p.hasCapability("LOGINDISABLED")) 517 p.login(u, pw); 518 else 519 throw new ProtocolException("No login methods supported!"); 520 if (proxyAuthUser != null) 521 p.proxyauth(proxyAuthUser); 522 } 523 524 539 public void setUsername(String user) { 540 this.user = user; 541 } 542 543 553 public void setPassword(String password) { 554 this.password = password; 555 } 556 557 562 IMAPProtocol getProtocol(IMAPFolder folder) 563 throws MessagingException { 564 IMAPProtocol p = null; 565 566 while (p == null) { 568 569 576 synchronized (pool) { 577 578 if (pool.authenticatedConnections.isEmpty() || 581 (pool.separateStoreConnection && 582 pool.authenticatedConnections.size() == 1) || 583 (pool.borrowedStoreConnections > 0 && 584 pool.authenticatedConnections.size() == 1)) { 585 586 if (debug) 587 out.println("DEBUG: no connections in the pool, " + 588 "creating a new one"); 589 try { 590 598 if (forcePasswordRefresh) { 599 InetAddress addr; 600 try { 601 addr = InetAddress.getByName(host); 602 } catch (UnknownHostException e) { 603 addr = null; 604 } 605 PasswordAuthentication pa = 606 session.requestPasswordAuthentication(addr, port, 607 name, null, user); 608 if (pa != null) { 609 user = pa.getUserName(); 610 password = pa.getPassword(); 611 } 612 } 613 p = new IMAPProtocol(name, host, port, 615 session.getDebug(), 616 session.getDebugOut(), 617 session.getProperties(), 618 isSSL 619 ); 620 login(p, user, password); 622 } catch(Exception ex1) { 623 if (p != null) 624 try { 625 p.disconnect(); 626 } catch (Exception ex2) { } 627 p = null; 628 } 629 630 if (p == null) 631 throw new MessagingException("connection failure"); 632 } else { 633 if (debug) 634 out.println("DEBUG: connection available -- size: " + 635 pool.authenticatedConnections.size()); 636 637 p = (IMAPProtocol)pool.authenticatedConnections.lastElement(); 639 pool.authenticatedConnections.removeElement(p); 640 641 long lastUsed = System.currentTimeMillis() - p.getTimestamp(); 643 if (lastUsed > pool.serverTimeoutInterval) { 644 try { 645 p.noop(); 648 } catch (ProtocolException pex) { 649 try { 650 p.removeResponseHandler(this); 651 p.disconnect(); 652 } catch (Exception ex) { } 653 p = null; 654 continue; } 656 } 657 658 p.removeResponseHandler(this); 660 } 661 662 timeoutConnections(); 664 665 if (folder != null) { 667 if (pool.folders == null) 668 pool.folders = new Vector (); 669 pool.folders.addElement(folder); 670 } 671 } 672 673 } 674 675 return p; 676 } 677 678 700 IMAPProtocol getStoreProtocol() throws ProtocolException { 701 IMAPProtocol p = null; 702 703 synchronized (pool) { 704 705 if (pool.authenticatedConnections.isEmpty()) { 708 if (pool.debug) 709 out.println("DEBUG: getStoreProtocol() - no connections " + 710 "in the pool, creating a new one"); 711 try { 712 p = new IMAPProtocol(name, host, port, 714 session.getDebug(), 715 session.getDebugOut(), 716 session.getProperties(), 717 isSSL 718 ); 719 login(p, user, password); 721 } catch(Exception ex1) { 722 if (p != null) 723 try { 724 p.logout(); 725 } catch (Exception ex2) { } 726 p = null; 727 } 728 729 if (p == null) 730 throw new ConnectionException( 731 "failed to create new store connection"); 732 733 p.addResponseHandler(this); 734 pool.authenticatedConnections.addElement(p); 735 736 } else { 737 if (pool.debug) 739 out.println("DEBUG: getStoreProtocol() - " + 740 "connection available -- size: " + 741 pool.authenticatedConnections.size()); 742 p = (IMAPProtocol)pool.authenticatedConnections.firstElement(); 743 } 744 745 if (!pool.separateStoreConnection) { 748 pool.borrowedStoreConnections++; 749 750 if (pool.debug) 751 out.println("DEBUG: getStoreProtocol() -- " + 752 "borrowedStoreConnections: " + 753 pool.borrowedStoreConnections); 754 } 755 756 timeoutConnections(); 757 758 return p; 759 760 } 761 } 762 763 768 boolean allowReadOnlySelect() { 769 String s = session.getProperty("mail." + name + 770 ".allowreadonlyselect"); 771 return s != null && s.equalsIgnoreCase("true"); 772 } 773 774 777 boolean hasSeparateStoreConnection() { 778 return pool.separateStoreConnection; 779 } 780 781 784 boolean getConnectionPoolDebug() { 785 return pool.debug; 786 } 787 788 791 boolean isConnectionPoolFull() { 792 793 synchronized (pool) { 794 if (pool.debug) 795 out.println("DEBUG: current size: " + 796 pool.authenticatedConnections.size() + 797 " pool size: " + pool.poolSize); 798 799 return (pool.authenticatedConnections.size() >= pool.poolSize); 800 801 } 802 } 803 804 807 void releaseProtocol(IMAPFolder folder, IMAPProtocol protocol) { 808 809 synchronized (pool) { 810 if (protocol != null) { 811 if (!isConnectionPoolFull()) { 814 protocol.addResponseHandler(this); 815 pool.authenticatedConnections.addElement(protocol); 816 817 if (debug) 818 out.println("DEBUG: added an " + 819 "Authenticated connection -- size: " + 820 pool.authenticatedConnections.size()); 821 } else { 822 if (debug) 823 out.println("DEBUG: pool is full, not adding " + 824 "an Authenticated connection"); 825 try { 826 protocol.logout(); 827 } catch (ProtocolException pex) {}; 828 } 829 } 830 831 if (pool.folders != null) 832 pool.folders.removeElement(folder); 833 834 timeoutConnections(); 835 } 836 } 837 838 841 void releaseStoreProtocol(IMAPProtocol protocol) { 842 843 if (protocol == null) 844 return; synchronized (pool) { 846 if (!pool.separateStoreConnection) { 849 pool.borrowedStoreConnections--; 850 851 if (pool.debug) 852 out.println("DEBUG: releaseStoreProtocol() -- " + 853 "borrowedStoreConnections: " + 854 pool.borrowedStoreConnections); 855 } 856 857 timeoutConnections(); 858 } 859 } 860 861 864 private void emptyConnectionPool(boolean force) { 865 866 synchronized (pool) { 867 for (int index = pool.authenticatedConnections.size() - 1; 868 index >= 0; --index) { 869 try { 870 IMAPProtocol p = (IMAPProtocol) 871 pool.authenticatedConnections.elementAt(index); 872 p.removeResponseHandler(this); 873 if (force) 874 p.disconnect(); 875 else 876 p.logout(); 877 } catch (ProtocolException pex) {}; 878 } 879 880 pool.authenticatedConnections.removeAllElements(); 881 } 882 883 if (pool.debug) 884 out.println("DEBUG: removed all authenticated connections"); 885 } 886 887 890 private void timeoutConnections() { 891 892 synchronized (pool) { 893 894 if (System.currentTimeMillis() - pool.lastTimePruned > 897 pool.pruningInterval && 898 pool.authenticatedConnections.size() > 1) { 899 900 if (pool.debug) { 901 out.println("DEBUG: checking for connections " + 902 "to prune: " + 903 (System.currentTimeMillis() - pool.lastTimePruned)); 904 out.println("DEBUG: clientTimeoutInterval: " + 905 pool.clientTimeoutInterval); 906 } 907 908 IMAPProtocol p; 909 910 for (int index = pool.authenticatedConnections.size() - 1; 914 index > 0; index--) { 915 p = (IMAPProtocol)pool.authenticatedConnections. 916 elementAt(index); 917 if (pool.debug) { 918 out.println("DEBUG: protocol last used: " + 919 (System.currentTimeMillis() - p.getTimestamp())); 920 } 921 if (System.currentTimeMillis() - p.getTimestamp() > 922 pool.clientTimeoutInterval) { 923 924 if (pool.debug) { 925 out.println("DEBUG: authenticated " + 926 "connection timed out"); 927 out.println("DEBUG: logging out " + 928 "the connection"); 929 } 930 931 p.removeResponseHandler(this); 932 pool.authenticatedConnections.removeElementAt(index); 933 934 try { 935 p.logout(); 936 } catch (ProtocolException pex) {} 937 } 938 } 939 pool.lastTimePruned = System.currentTimeMillis(); 940 } 941 } 942 } 943 944 947 int getFetchBlockSize() { 948 return blksize; 949 } 950 951 954 Session getSession() { 955 return session; 956 } 957 958 961 int getStatusCacheTimeout() { 962 return statusCacheTimeout; 963 } 964 965 968 int getAppendBufferSize() { 969 return appendBufferSize; 970 } 971 972 978 public boolean hasCapability(String capability) throws MessagingException { 979 IMAPProtocol p = null; 980 try { 981 p = getStoreProtocol(); 982 return p.hasCapability(capability); 983 } catch (ProtocolException pex) { 984 if (p == null) { cleanup(); 987 } 988 throw new MessagingException(pex.getMessage(), pex); 989 } finally { 990 releaseStoreProtocol(p); 991 } 992 } 993 994 998 public synchronized boolean isConnected() { 999 if (!super.isConnected()) 1000 return false; 1003 1004 1019 1020 IMAPProtocol p = null; 1021 try { 1022 p = getStoreProtocol(); 1023 p.noop(); 1024 } catch (ProtocolException pex) { 1025 if (p == null) { cleanup(); 1028 } 1029 } finally { 1031 releaseStoreProtocol(p); 1032 } 1033 1034 1035 return super.isConnected(); 1036 } 1037 1038 1041 public void close() throws MessagingException { 1042 if (!super.isConnected()) return; 1044 1045 IMAPProtocol protocol = null; 1046 try { 1047 boolean isEmpty; 1048 synchronized (pool) { 1049 isEmpty = pool.authenticatedConnections.isEmpty(); 1052 } 1053 1062 if (isEmpty) { 1063 if (pool.debug) 1064 out.println("DEBUG: close() - no connections "); 1065 cleanup(); 1066 return; 1067 } 1068 1069 protocol = getStoreProtocol(); 1070 1076 synchronized (pool) { 1077 pool.authenticatedConnections.removeElement(protocol); 1078 } 1079 1080 1094 protocol.logout(); 1095 } catch (ProtocolException pex) { 1096 cleanup(); 1098 throw new MessagingException(pex.getMessage(), pex); 1099 } finally { 1100 releaseStoreProtocol(protocol); 1101 } 1102 } 1103 1104 protected void finalize() throws Throwable { 1105 super.finalize(); 1106 close(); 1107 } 1108 1109 private synchronized void cleanup() { 1111 cleanup(false); 1112 } 1113 1114 1121 private synchronized void cleanup(boolean force) { 1122 if (debug) 1123 out.println("DEBUG: IMAPStore cleanup, force " + force); 1124 1125 Vector foldersCopy = null; 1126 boolean done = true; 1127 1128 for (;;) { 1136 synchronized (pool) { 1139 if (pool.folders != null) { 1140 done = false; 1141 foldersCopy = pool.folders; 1142 pool.folders = null; 1143 } else { 1144 done = true; 1145 } 1146 } 1147 if (done) 1148 break; 1149 1150 for (int i = 0, fsize = foldersCopy.size(); i < fsize; i++) { 1152 IMAPFolder f = (IMAPFolder)foldersCopy.elementAt(i); 1153 1154 try { 1155 if (force) { 1156 if (debug) 1157 out.println("DEBUG: force folder to close"); 1158 f.forceClose(); 1162 } else { 1163 if (debug) 1164 out.println("DEBUG: close folder"); 1165 f.close(false); 1166 } 1167 } catch (MessagingException mex) { 1168 } catch (IllegalStateException ex) { 1170 } 1172 } 1173 1174 } 1175 1176 synchronized (pool) { 1177 emptyConnectionPool(force); 1178 } 1179 1180 try { 1182 super.close(); 1183 } catch (MessagingException mex) { } 1184 if (debug) 1185 out.println("DEBUG: IMAPStore cleanup done"); 1186 } 1187 1188 1192 public Folder getDefaultFolder() throws MessagingException { 1193 checkConnected(); 1194 return new DefaultFolder(this); 1195 } 1196 1197 1200 public Folder getFolder(String name) throws MessagingException { 1201 checkConnected(); 1202 return new IMAPFolder(name, IMAPFolder.UNKNOWN_SEPARATOR, this); 1203 } 1204 1205 1208 public Folder getFolder(URLName url) throws MessagingException { 1209 checkConnected(); 1210 return new IMAPFolder(url.getFile(), 1211 IMAPFolder.UNKNOWN_SEPARATOR, 1212 this); 1213 } 1214 1215 1219 public Folder[] getPersonalNamespaces() throws MessagingException { 1220 Namespaces ns = getNamespaces(); 1221 if (ns == null || ns.personal == null) 1222 return super.getPersonalNamespaces(); 1223 return namespaceToFolders(ns.personal, null); 1224 } 1225 1226 1230 public Folder[] getUserNamespaces(String user) 1231 throws MessagingException { 1232 Namespaces ns = getNamespaces(); 1233 if (ns == null || ns.otherUsers == null) 1234 return super.getUserNamespaces(user); 1235 return namespaceToFolders(ns.otherUsers, user); 1236 } 1237 1238 1242 public Folder[] getSharedNamespaces() throws MessagingException { 1243 Namespaces ns = getNamespaces(); 1244 if (ns == null || ns.shared == null) 1245 return super.getSharedNamespaces(); 1246 return namespaceToFolders(ns.shared, null); 1247 } 1248 1249 private synchronized Namespaces getNamespaces() throws MessagingException { 1250 checkConnected(); 1251 1252 IMAPProtocol p = null; 1253 1254 if (namespaces == null) { 1255 try { 1256 p = getStoreProtocol(); 1257 namespaces = p.namespace(); 1258 } catch (BadCommandException bex) { 1259 } catch (ConnectionException cex) { 1261 throw new StoreClosedException(this, cex.getMessage()); 1262 } catch (ProtocolException pex) { 1263 throw new MessagingException(pex.getMessage(), pex); 1264 } finally { 1265 releaseStoreProtocol(p); 1266 if (p == null) { cleanup(); 1269 } 1270 } 1271 } 1272 return namespaces; 1273 } 1274 1275 private Folder[] namespaceToFolders(Namespaces.Namespace[] ns, 1276 String user) { 1277 Folder[] fa = new Folder[ns.length]; 1278 for (int i = 0; i < fa.length; i++) { 1279 String name = ns[i].prefix; 1280 if (user == null) { 1281 int len = name.length(); 1283 if ( len > 0 && name.charAt(len - 1) == ns[i].delimiter) 1284 name = name.substring(0, len - 1); 1285 } else { 1286 name += user; 1288 } 1289 fa[i] = new IMAPFolder(name, ns[i].delimiter, this, user == null); 1290 } 1291 return fa; 1292 } 1293 1294 1310 public Quota[] getQuota(String root) throws MessagingException { 1311 Quota[] qa = null; 1312 1313 IMAPProtocol p = null; 1314 try { 1315 p = getStoreProtocol(); 1316 qa = p.getQuotaRoot(root); 1317 } catch (BadCommandException bex) { 1318 throw new MessagingException("QUOTA not supported", bex); 1319 } catch (ConnectionException cex) { 1320 throw new StoreClosedException(this, cex.getMessage()); 1321 } catch (ProtocolException pex) { 1322 throw new MessagingException(pex.getMessage(), pex); 1323 } finally { 1324 releaseStoreProtocol(p); 1325 if (p == null) { cleanup(); 1328 } 1329 } 1330 return qa; 1331 } 1332 1333 1342 public void setQuota(Quota quota) throws MessagingException { 1343 IMAPProtocol p = null; 1344 try { 1345 p = getStoreProtocol(); 1346 p.setQuota(quota); 1347 } catch (BadCommandException bex) { 1348 throw new MessagingException("QUOTA not supported", bex); 1349 } catch (ConnectionException cex) { 1350 throw new StoreClosedException(this, cex.getMessage()); 1351 } catch (ProtocolException pex) { 1352 throw new MessagingException(pex.getMessage(), pex); 1353 } finally { 1354 releaseStoreProtocol(p); 1355 if (p == null) { cleanup(); 1358 } 1359 } 1360 } 1361 1362 private void checkConnected() { 1363 if (!super.isConnected()) 1364 throw new IllegalStateException ("Not connected"); 1365 } 1366 1367 1370 public void handleResponse(Response r) { 1371 if (r.isOK() || r.isNO() || r.isBAD() || r.isBYE()) 1373 handleResponseCode(r); 1374 if (r.isBYE()) { 1375 if (debug) 1376 out.println("DEBUG: IMAPStore connection dead"); 1377 if (super.isConnected()) cleanup(r.isSynthetic()); 1380 return; 1381 } 1382 } 1383 1384 1388 void handleResponseCode(Response r) { 1389 String s = r.getRest(); boolean isAlert = false; 1391 if (s.startsWith("[")) { int i = s.indexOf(']'); 1393 if (i > 0 && s.substring(0, i + 1).equalsIgnoreCase("[ALERT]")) 1395 isAlert = true; 1396 s = s.substring(i + 1).trim(); 1398 } 1399 if (isAlert) 1400 notifyStoreListeners(StoreEvent.ALERT, s); 1401 else if (r.isUnTagged() && s.length() > 0) 1402 notifyStoreListeners(StoreEvent.NOTICE, s); 1406 } 1407} 1408 | Popular Tags |