1 21 22 27 28 package javax.mail; 29 30 import java.lang.reflect.*; 31 import java.io.*; 32 import java.net.*; 33 import java.security.*; 34 import java.util.Enumeration ; 35 import java.util.Hashtable ; 36 import java.util.Properties ; 37 import java.util.StringTokenizer ; 38 import java.util.Vector ; 39 40 import javax.activation.*; 41 42 import com.sun.mail.util.LineInputStream; 43 44 173 174 public final class Session { 175 176 private final Properties props; 177 private final Authenticator authenticator; 178 private final Hashtable authTable = new Hashtable (); 179 private boolean debug = false; 180 private PrintStream out; private final Vector providers = new Vector (); 182 private final Hashtable providersByProtocol = new Hashtable (); 183 private final Hashtable providersByClassName = new Hashtable (); 184 private final Properties addressMap = new Properties (); 185 private static Session defaultSession = null; 188 189 private static final String version = "1.4ea"; 191 192 private Session(Properties props, Authenticator authenticator) { 194 this.props = props; 195 this.authenticator = authenticator; 196 197 if (Boolean.valueOf(props.getProperty("mail.debug")).booleanValue()) 198 debug = true; 199 200 if (debug) 201 pr("DEBUG: JavaMail version " + version); 202 203 Class cl; 205 if (authenticator != null) 206 cl = authenticator.getClass(); 207 else 208 cl = this.getClass(); 209 loadProviders(cl); 211 loadAddressMap(cl); 212 } 213 214 230 public static Session getInstance(Properties props, 231 Authenticator authenticator) { 232 return new Session (props, authenticator); 233 } 234 235 248 public static Session getInstance(Properties props) { 249 return new Session (props, null); 250 } 251 252 296 public static synchronized Session getDefaultInstance(Properties props, 297 Authenticator authenticator) { 298 if (defaultSession == null) 299 defaultSession = new Session (props, authenticator); 300 else { 301 if (defaultSession.authenticator == authenticator) 303 ; else if (defaultSession.authenticator != null && 305 authenticator != null && 306 defaultSession.authenticator.getClass().getClassLoader() == 307 authenticator.getClass().getClassLoader()) 308 ; else 310 throw new SecurityException ("Access to default session denied"); 312 } 313 314 return defaultSession; 315 } 316 317 338 public static Session getDefaultInstance(Properties props) { 339 return getDefaultInstance(props, null); 340 } 341 342 357 public synchronized void setDebug(boolean debug) { 358 this.debug = debug; 359 if (debug) 360 pr("DEBUG: setDebug: JavaMail version " + version); 361 } 362 363 368 public synchronized boolean getDebug() { 369 return debug; 370 } 371 372 382 public synchronized void setDebugOut(PrintStream out) { 383 this.out = out; 384 } 385 386 393 public synchronized PrintStream getDebugOut() { 394 if (out == null) 395 return System.out; 396 else 397 return out; 398 } 399 400 407 public synchronized Provider [] getProviders() { 408 Provider [] _providers = new Provider [providers.size()]; 409 providers.copyInto(_providers); 410 return _providers; 411 } 412 413 427 public synchronized Provider getProvider(String protocol) 428 throws NoSuchProviderException { 429 430 if (protocol == null || protocol.length() <= 0) { 431 throw new NoSuchProviderException ("Invalid protocol: null"); 432 } 433 434 Provider _provider = null; 435 436 String _className = props.getProperty("mail."+protocol+".class"); 438 if (_className != null) { 439 if (debug) { 440 pr("DEBUG: mail."+protocol+ 441 ".class property exists and points to " + 442 _className); 443 } 444 _provider = (Provider )providersByClassName.get(_className); 445 } 446 447 if (_provider != null) { 448 return _provider; 449 } else { 450 _provider = (Provider )providersByProtocol.get(protocol); 452 } 453 454 if (_provider == null) { 455 throw new NoSuchProviderException ("No provider for " + protocol); 456 } else { 457 if (debug) { 458 pr("DEBUG: getProvider() returning " + 459 _provider.toString()); 460 } 461 return _provider; 462 } 463 } 464 465 474 public synchronized void setProvider(Provider provider) 475 throws NoSuchProviderException { 476 if (provider == null) { 477 throw new NoSuchProviderException ("Can't set null provider"); 478 } 479 providersByProtocol.put(provider.getProtocol(), provider); 480 props.put("mail." + provider.getProtocol() + ".class", 481 provider.getClassName()); 482 } 483 484 485 495 public Store getStore() throws NoSuchProviderException { 496 return getStore(getProperty("mail.store.protocol")); 497 } 498 499 509 public Store getStore(String protocol) throws NoSuchProviderException { 510 return getStore(new URLName (protocol, null, -1, null, null, null)); 511 } 512 513 514 528 public Store getStore(URLName url) throws NoSuchProviderException { 529 String protocol = url.getProtocol(); 530 Provider p = getProvider(protocol); 531 return getStore(p, url); 532 } 533 534 543 public Store getStore(Provider provider) throws NoSuchProviderException { 544 return getStore(provider, null); 545 } 546 547 548 560 private Store getStore(Provider provider, URLName url) 561 throws NoSuchProviderException { 562 563 if (provider == null || provider.getType() != Provider.Type.STORE ) { 565 throw new NoSuchProviderException ("invalid provider"); 566 } 567 568 try { 569 return (Store ) getService(provider, url); 570 } catch (ClassCastException cce) { 571 throw new NoSuchProviderException ("incorrect class"); 572 } 573 } 574 575 599 public Folder getFolder(URLName url) 600 throws MessagingException { 601 Store store = getStore(url); 603 store.connect(); 604 return store.getFolder(url); 605 } 606 607 616 public Transport getTransport() throws NoSuchProviderException { 617 return getTransport(getProperty("mail.transport.protocol")); 618 } 619 620 629 public Transport getTransport(String protocol) 630 throws NoSuchProviderException { 631 return getTransport(new URLName (protocol, null, -1, null, null, null)); 632 } 633 634 635 648 public Transport getTransport(URLName url) throws NoSuchProviderException { 649 String protocol = url.getProtocol(); 650 Provider p = getProvider(protocol); 651 return getTransport(p, url); 652 } 653 654 663 public Transport getTransport(Provider provider) 664 throws NoSuchProviderException { 665 return getTransport(provider, null); 666 } 667 668 678 public Transport getTransport(Address address) 679 throws NoSuchProviderException { 680 681 String transportProtocol = (String )addressMap.get(address.getType()); 682 if (transportProtocol == null) { 683 throw new NoSuchProviderException ("No provider for Address type: "+ 684 address.getType()); 685 } else { 686 return getTransport(transportProtocol); 687 } 688 } 689 690 699 700 private Transport getTransport(Provider provider, URLName url) 701 throws NoSuchProviderException { 702 if (provider == null || provider.getType() != Provider.Type.TRANSPORT) { 704 throw new NoSuchProviderException ("invalid provider"); 705 } 706 707 try { 708 return (Transport ) getService(provider, url); 709 } catch (ClassCastException cce) { 710 throw new NoSuchProviderException ("incorrect class"); 711 } 712 } 713 714 726 private Object getService(Provider provider, URLName url) 727 throws NoSuchProviderException { 728 if (provider == null) { 730 throw new NoSuchProviderException ("null"); 731 } 732 733 if (url == null) { 735 url = new URLName (provider.getProtocol(), null, -1, 736 null, null, null); 737 } 738 739 Object service = null; 740 741 ClassLoader cl; 743 if (authenticator != null) 744 cl = authenticator.getClass().getClassLoader(); 745 else 746 cl = this.getClass().getClassLoader(); 747 748 Class serviceClass = null; 750 try { 751 ClassLoader ccl = getContextClassLoader(); 753 if (ccl != null) 754 try { 755 serviceClass = ccl.loadClass(provider.getClassName()); 756 } catch (ClassNotFoundException ex) { } 757 if (serviceClass == null) 758 serviceClass = cl.loadClass(provider.getClassName()); 759 } catch (Exception ex1) { 760 try { 764 serviceClass = Class.forName(provider.getClassName()); 765 } catch (Exception ex) { 766 if (debug) ex.printStackTrace(getDebugOut()); 768 throw new NoSuchProviderException (provider.getProtocol()); 769 } 770 } 771 772 try { 774 Class [] c = {javax.mail.Session .class, javax.mail.URLName .class}; 775 Constructor cons = serviceClass.getConstructor(c); 776 777 Object [] o = {this, url}; 778 service = cons.newInstance(o); 779 780 } catch (Exception ex) { 781 if (debug) ex.printStackTrace(getDebugOut()); 782 throw new NoSuchProviderException (provider.getProtocol()); 783 } 784 785 return service; 786 } 787 788 796 public void setPasswordAuthentication(URLName url, 797 PasswordAuthentication pw) { 798 if (pw == null) 799 authTable.remove(url); 800 else 801 authTable.put(url, pw); 802 } 803 804 810 public PasswordAuthentication getPasswordAuthentication(URLName url) { 811 return (PasswordAuthentication )authTable.get(url); 812 } 813 814 833 public PasswordAuthentication requestPasswordAuthentication( 834 InetAddress addr, int port, 835 String protocol, String prompt, String defaultUserName) { 836 837 if (authenticator != null) { 838 return authenticator.requestPasswordAuthentication( 839 addr, port, protocol, prompt, defaultUserName); 840 } else { 841 return null; 842 } 843 } 844 845 850 public Properties getProperties() { 851 return props; 852 } 853 854 860 public String getProperty(String name) { 861 return props.getProperty(name); 862 } 863 864 867 private void loadProviders(Class cl) { 868 StreamLoader loader = new StreamLoader() { 869 public void load(InputStream is) throws IOException { 870 loadProvidersFromStream(is); 871 } 872 }; 873 874 try { 876 String res = System.getProperty("java.home") + 877 File.separator + "lib" + 878 File.separator + "javamail.providers"; 879 loadFile(res, loader); 880 } catch (SecurityException sex) { 881 if (debug) 882 pr("DEBUG: can't get java.home: " + sex); 883 } 884 885 loadAllResources("META-INF/javamail.providers", cl, loader); 887 888 loadResource("/META-INF/javamail.default.providers", cl, loader); 890 891 if (providers.size() == 0) { 892 if (debug) 893 pr("DEBUG: failed to load any providers, using defaults"); 894 addProvider(new Provider (Provider.Type.STORE, 896 "imap", "com.sun.mail.imap.IMAPStore", 897 "Sun Microsystems, Inc.", version)); 898 addProvider(new Provider (Provider.Type.STORE, 899 "imaps", "com.sun.mail.imap.IMAPSSLStore", 900 "Sun Microsystems, Inc.", version)); 901 addProvider(new Provider (Provider.Type.STORE, 902 "pop3", "com.sun.mail.pop3.POP3Store", 903 "Sun Microsystems, Inc.", version)); 904 addProvider(new Provider (Provider.Type.STORE, 905 "pop3s", "com.sun.mail.pop3.POP3SSLStore", 906 "Sun Microsystems, Inc.", version)); 907 addProvider(new Provider (Provider.Type.TRANSPORT, 908 "smtp", "com.sun.mail.smtp.SMTPTransport", 909 "Sun Microsystems, Inc.", version)); 910 addProvider(new Provider (Provider.Type.TRANSPORT, 911 "smtps", "com.sun.mail.smtp.SMTPSSLTransport", 912 "Sun Microsystems, Inc.", version)); 913 } 914 915 if (debug) { 916 pr("DEBUG: Tables of loaded providers"); 918 pr("DEBUG: Providers Listed By Class Name: " + 919 providersByClassName.toString()); 920 pr("DEBUG: Providers Listed By Protocol: " + 921 providersByProtocol.toString()); 922 } 923 } 924 925 private void loadProvidersFromStream(InputStream is) 926 throws IOException { 927 if (is != null) { 928 LineInputStream lis = new LineInputStream(is); 929 String currLine; 930 931 while ((currLine = lis.readLine()) != null) { 933 934 if (currLine.startsWith("#")) 935 continue; 936 Provider.Type type = null; 937 String protocol = null, className = null; 938 String vendor = null, version = null; 939 940 StringTokenizer tuples = new StringTokenizer (currLine,";"); 942 while (tuples.hasMoreTokens()) { 943 String currTuple = tuples.nextToken().trim(); 944 945 int sep = currTuple.indexOf("="); 947 if (currTuple.startsWith("protocol=")) { 948 protocol = currTuple.substring(sep+1); 949 } else if (currTuple.startsWith("type=")) { 950 String strType = currTuple.substring(sep+1); 951 if (strType.equalsIgnoreCase("store")) { 952 type = Provider.Type.STORE; 953 } else if (strType.equalsIgnoreCase("transport")) { 954 type = Provider.Type.TRANSPORT; 955 } 956 } else if (currTuple.startsWith("class=")) { 957 className = currTuple.substring(sep+1); 958 } else if (currTuple.startsWith("vendor=")) { 959 vendor = currTuple.substring(sep+1); 960 } else if (currTuple.startsWith("version=")) { 961 version = currTuple.substring(sep+1); 962 } 963 } 964 965 if (type == null || protocol == null || className == null 967 || protocol.length() <= 0 || className.length() <= 0) { 968 969 if (debug) 970 pr("DEBUG: Bad provider entry: " + currLine); 971 continue; 972 } 973 Provider provider = new Provider (type, protocol, className, 974 vendor, version); 975 976 addProvider(provider); 978 } 979 } 980 } 981 982 988 public synchronized void addProvider(Provider provider) { 989 providers.addElement(provider); 990 providersByClassName.put(provider.getClassName(), provider); 991 if (!providersByProtocol.containsKey(provider.getProtocol())) 992 providersByProtocol.put(provider.getProtocol(), provider); 993 } 994 995 private void loadAddressMap(Class cl) { 998 StreamLoader loader = new StreamLoader() { 999 public void load(InputStream is) throws IOException { 1000 addressMap.load(is); 1001 } 1002 }; 1003 1004 loadResource("/META-INF/javamail.default.address.map", cl, loader); 1006 1007 loadAllResources("META-INF/javamail.address.map", cl, loader); 1009 1010 try { 1012 String res = System.getProperty("java.home") + 1013 File.separator + "lib" + 1014 File.separator + "javamail.address.map"; 1015 loadFile(res, loader); 1016 } catch (SecurityException sex) { 1017 if (debug) 1018 pr("DEBUG: can't get java.home: " + sex); 1019 } 1020 1021 if (addressMap.isEmpty()) { 1022 if (debug) 1023 pr("DEBUG: failed to load address map, using defaults"); 1024 addressMap.put("rfc822", "smtp"); 1025 } 1026 } 1027 1028 1039 public synchronized void setProtocolForAddress(String addresstype, 1040 String protocol) { 1041 if (protocol == null) 1042 addressMap.remove(addresstype); 1043 else 1044 addressMap.put(addresstype, protocol); 1045 } 1046 1047 1050 private void loadFile(String name, StreamLoader loader) { 1051 InputStream clis = null; 1052 try { 1053 clis = new BufferedInputStream(new FileInputStream(name)); 1054 if (clis != null) { 1055 loader.load(clis); 1056 if (debug) 1057 pr("DEBUG: successfully loaded file: " + name); 1058 } else { 1059 if (debug) 1060 pr("DEBUG: not loading file: " + name); 1061 } 1062 } catch (IOException e) { 1063 if (debug) 1064 pr("DEBUG: " + e); 1065 } catch (SecurityException sex) { 1066 if (debug) 1067 pr("DEBUG: " + sex); 1068 } finally { 1069 try { 1070 if (clis != null) 1071 clis.close(); 1072 } catch (IOException ex) { } } 1074 } 1075 1076 1079 private void loadResource(String name, Class cl, StreamLoader loader) { 1080 InputStream clis = null; 1081 try { 1082 clis = getResourceAsStream(cl, name); 1083 if (clis != null) { 1084 loader.load(clis); 1085 if (debug) 1086 pr("DEBUG: successfully loaded resource: " + name); 1087 } else { 1088 if (debug) 1089 pr("DEBUG: not loading resource: " + name); 1090 } 1091 } catch (IOException e) { 1092 if (debug) 1093 pr("DEBUG: " + e); 1094 } catch (SecurityException sex) { 1095 if (debug) 1096 pr("DEBUG: " + sex); 1097 } finally { 1098 try { 1099 if (clis != null) 1100 clis.close(); 1101 } catch (IOException ex) { } } 1103 } 1104 1105 1108 private void loadAllResources(String name, Class cl, StreamLoader loader) { 1109 boolean anyLoaded = false; 1110 try { 1111 URL[] urls; 1112 ClassLoader cld = null; 1113 cld = getContextClassLoader(); 1115 if (cld == null) 1116 cld = cl.getClassLoader(); 1117 if (cld != null) 1118 urls = getResources(cld, name); 1119 else 1120 urls = getSystemResources(name); 1121 if (urls != null) { 1122 for (int i = 0; i < urls.length; i++) { 1123 URL url = urls[i]; 1124 InputStream clis = null; 1125 if (debug) 1126 pr("DEBUG: URL " + url); 1127 try { 1128 clis = openStream(url); 1129 if (clis != null) { 1130 loader.load(clis); 1131 anyLoaded = true; 1132 if (debug) 1133 pr("DEBUG: successfully loaded resource: " + 1134 url); 1135 } else { 1136 if (debug) 1137 pr("DEBUG: not loading resource: " + url); 1138 } 1139 } catch (IOException ioex) { 1140 if (debug) 1141 pr("DEBUG: " + ioex); 1142 } catch (SecurityException sex) { 1143 if (debug) 1144 pr("DEBUG: " + sex); 1145 } finally { 1146 try { 1147 if (clis != null) 1148 clis.close(); 1149 } catch (IOException cex) { } 1150 } 1151 } 1152 } 1153 } catch (Exception ex) { 1154 if (debug) 1155 pr("DEBUG: " + ex); 1156 } 1157 1158 if (!anyLoaded) { 1160 if (debug) 1161 pr("DEBUG: !anyLoaded"); 1162 loadResource("/" + name, cl, loader); 1163 } 1164 } 1165 1166 private void pr(String str) { 1167 getDebugOut().println(str); 1168 } 1169 1170 1173 1174 private static ClassLoader getContextClassLoader() { 1175 return (ClassLoader ) 1176 AccessController.doPrivileged(new PrivilegedAction() { 1177 public Object run() { 1178 ClassLoader cl = null; 1179 try { 1180 cl = Thread.currentThread().getContextClassLoader(); 1181 } catch (SecurityException ex) { } 1182 return cl; 1183 } 1184 }); 1185 } 1186 1187 private static InputStream getResourceAsStream(final Class c, 1188 final String name) throws IOException { 1189 try { 1190 return (InputStream) 1191 AccessController.doPrivileged(new PrivilegedExceptionAction() { 1192 public Object run() throws IOException { 1193 return c.getResourceAsStream(name); 1194 } 1195 }); 1196 } catch (PrivilegedActionException e) { 1197 throw (IOException)e.getException(); 1198 } 1199 } 1200 1201 private static URL[] getResources(final ClassLoader cl, final String name) { 1202 return (URL[]) 1203 AccessController.doPrivileged(new PrivilegedAction() { 1204 public Object run() { 1205 URL[] ret = null; 1206 try { 1207 Vector v = new Vector (); 1208 Enumeration e = cl.getResources(name); 1209 while (e != null && e.hasMoreElements()) { 1210 URL url = (URL)e.nextElement(); 1211 if (url != null) 1212 v.addElement(url); 1213 } 1214 if (v.size() > 0) { 1215 ret = new URL[v.size()]; 1216 v.copyInto(ret); 1217 } 1218 } catch (IOException ioex) { 1219 } catch (SecurityException ex) { } 1220 return ret; 1221 } 1222 }); 1223 } 1224 1225 private static URL[] getSystemResources(final String name) { 1226 return (URL[]) 1227 AccessController.doPrivileged(new PrivilegedAction() { 1228 public Object run() { 1229 URL[] ret = null; 1230 try { 1231 Vector v = new Vector (); 1232 Enumeration e = ClassLoader.getSystemResources(name); 1233 while (e != null && e.hasMoreElements()) { 1234 URL url = (URL)e.nextElement(); 1235 if (url != null) 1236 v.addElement(url); 1237 } 1238 if (v.size() > 0) { 1239 ret = new URL[v.size()]; 1240 v.copyInto(ret); 1241 } 1242 } catch (IOException ioex) { 1243 } catch (SecurityException ex) { } 1244 return ret; 1245 } 1246 }); 1247 } 1248 1249 private static InputStream openStream(final URL url) throws IOException { 1250 try { 1251 return (InputStream) 1252 AccessController.doPrivileged(new PrivilegedExceptionAction() { 1253 public Object run() throws IOException { 1254 return url.openStream(); 1255 } 1256 }); 1257 } catch (PrivilegedActionException e) { 1258 throw (IOException)e.getException(); 1259 } 1260 } 1261} 1262 1263 1267interface StreamLoader { 1268 public void load(InputStream is) throws IOException; 1269} 1270 | Popular Tags |