- /*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package javax.mail;
-
- import java.lang.*;
- import java.lang.reflect.*;
- import java.io.*;
- import java.net.*;
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Properties;
- import java.util.StringTokenizer;
- import java.util.Vector;
-
- import javax.activation.*;
-
- import com.sun.mail.util.LineInputStream;
-
- /**
- * The Session class represents a mail session and is not subclassed.
- * It collects together properties and defaults used by the mail API's.
- * A single default session can be shared by multiple applications on the
- * desktop. Unshared sessions can also be created.
- *
- * @version 1.47, 00/10/23
- * @author John Mani
- * @author Bill Shannon
- * @author Max Spivak
- */
-
- public final class Session {
-
- private Properties props;
- private Authenticator authenticator;
- private Hashtable authTable = new Hashtable();
- private boolean debug = false;
- private Vector providers = new Vector();
- private Hashtable providersByProtocol = new Hashtable();
- private Hashtable providersByClassName = new Hashtable();
- private Properties addressMap = new Properties(); // maps type to protocol
- private static Method getResources = null;
- private static Method getSystemResources = null;
-
- static {
- try {
- Class c = java.lang.ClassLoader.class;
- // assume both succeed or both fail
- getResources = c.getMethod("getResources",
- new Class[] { String.class });
- getSystemResources = c.getMethod("getSystemResources",
- new Class[] { String.class });
- } catch (Throwable t) { } // ignore any errors
- }
-
- // The default session.
- private static Session defaultSession = null;
-
- // Constructor is not public
- private Session(Properties props, Authenticator authenticator) {
- this.props = props;
- this.authenticator = authenticator;
-
- if (Boolean.valueOf(props.getProperty("mail.debug")).booleanValue())
- debug = true;
-
- // get the Class associated with the Authenticator
- Class cl;
- if (authenticator != null)
- cl = authenticator.getClass();
- else
- cl = this.getClass();
- // load the resources
- loadProviders(cl);
- loadAddressMap(cl);
- }
-
- /**
- * Get a new Session object.
- *
- * @param props Properties object that hold relevant properties.<br>
- * It is expected that the client supplies values
- * for the properties listed in Appendix A of the
- * JavaMail spec (particularly mail.store.protocol,
- * mail.transport.protocol, mail.host, mail.user,
- * and mail.from) as the defaults are unlikely to
- * work in all cases.
- * @param authenticator Authenticator object used to call back to
- * the application when a user name and password is
- * needed.
- * @return a new Session object
- * @see javax.mail.Authenticator
- */
- public static Session getInstance(Properties props,
- Authenticator authenticator) {
- return new Session(props, authenticator);
- }
-
- /**
- * Get a new Session object.
- *
- * @param props Properties object that hold relevant properties.<br>
- * It is expected that the client supplies values
- * for the properties listed in Appendix A of the
- * JavaMail spec (particularly mail.store.protocol,
- * mail.transport.protocol, mail.host, mail.user,
- * and mail.from) as the defaults are unlikely to
- * work in all cases.
- * @return a new Session object
- * @since JavaMail 1.2
- */
- public static Session getInstance(Properties props) {
- return new Session(props, null);
- }
-
- /**
- * Get the default Session object. If a default has not yet been
- * setup, a new Session object is created and installed as the
- * default. <p>
- *
- * Since the default session is potentially available to all
- * code executing in the same Java virtual machine, and the session
- * can contain security sensitive information such as user names
- * and passwords, access to the default session is restricted.
- * The Authenticator object, which must be created by the caller,
- * is used indirectly to check access permission. The Authenticator
- * object passed in when the session is created is compared with
- * the Authenticator object passed in to subsequent requests to
- * get the default session. If both objects are the same, or are
- * from the same ClassLoader, the request is allowed. Otherwise,
- * it is denied. <p>
- *
- * Note that if the Authenticator object used to create the session
- * is null, anyone can get the default session by passing in null. <p>
- *
- * In JDK 1.2, additional security Permission objects may be used to
- * control access to the default session.
- *
- * @param props Properties object. Used only if a new Session
- * object is created.<br>
- * It is expected that the client supplies values
- * for the properties listed in Appendix A of the
- * JavaMail spec (particularly mail.store.protocol,
- * mail.transport.protocol, mail.host, mail.user,
- * and mail.from) as the defaults are unlikely to
- * work in all cases.
- * @param authenticator Authenticator object. Used only if a
- * new Session object is created. Otherwise,
- * it must match the Authenticator used to create
- * the Session.
- * @return the default Session object
- */
- public static Session getDefaultInstance(Properties props,
- Authenticator authenticator) {
- if (defaultSession == null)
- defaultSession = new Session(props, authenticator);
- else {
- // have to check whether caller is allowed to see default session
- if (defaultSession.authenticator == authenticator)
- ; // either same object or both null, either way OK
- else if (defaultSession.authenticator != null &&
- authenticator != null &&
- defaultSession.authenticator.getClass().getClassLoader() ==
- authenticator.getClass().getClassLoader())
- ; // both objects came from the same class loader, OK
- else
- // anything else is not allowed
- throw new SecurityException("Access to default session denied");
- }
-
- return defaultSession;
- }
-
- /**
- * Get the default Session object. If a default has not yet been
- * setup, a new Session object is created and installed as the
- * default. <p>
- *
- * Note that a default session created with no Authenticator is
- * available to all code executing in the same Java virtual
- * machine, and the session can contain security sensitive
- * information such as user names and passwords.
- *
- * @param props Properties object. Used only if a new Session
- * object is created.<br>
- * It is expected that the client supplies values
- * for the properties listed in Appendix A of the
- * JavaMail spec (particularly mail.store.protocol,
- * mail.transport.protocol, mail.host, mail.user,
- * and mail.from) as the defaults are unlikely to
- * work in all cases.
- * @return the default Session object
- * @since JavaMail 1.2
- */
- public static Session getDefaultInstance(Properties props) {
- return getDefaultInstance(props, null);
- }
-
- /**
- * Set the debug setting for this Session.
- * <p>
- * Since the debug setting can be turned on only after the Session
- * has been created, to turn on debugging in the Session
- * constructor, set the property <code>mail.debug</code> in the
- * Properties object passed in to the constructor to true. The
- * value of the <code>mail.debug</code> property is used to
- * initialize the per-Session debugging flag. Subsequent calls to
- * the <code>setDebug</code> method manipulate the per-Session
- * debugging flag and have no affect on the <code>mail.debug</code>
- * property.
- *
- * @param debug Debug setting
- */
- public void setDebug(boolean debug) {
- this.debug = debug;
- }
-
- /**
- * Get the debug setting for this Session.
- *
- * @return current debug setting
- */
- public boolean getDebug() {
- return debug;
- }
-
- /**
- * This method returns an array of all the implementations installed
- * via the javamail.[default.]providers files that can
- * be loaded using the ClassLoader available to this application.
- *
- * @return Array of configured providers
- */
- public Provider[] getProviders() {
- Provider[] _providers = new Provider[providers.size()];
- providers.copyInto(_providers);
- return _providers;
- }
-
- /**
- * Returns the default Provider for the protocol
- * specified. Checks mail.<protocol>.class property
- * first and if it exists, returns the Provider
- * associated with this implementation. If it doesn't exist,
- * returns the Provider that appeared first in the
- * configuration files. If an implementation for the protocol
- * isn't found, throws NoSuchProviderException
- *
- * @param protocol Configured protocol (i.e. smtp, imap, etc)
- * @return Currently configured Provider for the specified protocol
- * @exception NoSuchProviderException If a provider for the given
- * protocol is not found.
- */
- public Provider getProvider(String protocol)
- throws NoSuchProviderException {
-
- if (protocol == null || protocol.length() <= 0) {
- throw new NoSuchProviderException("Invalid protocol: null");
- }
-
- Provider _provider = null;
-
- // check if the mail.<protocol>.class property exists
- String _className = props.getProperty("mail."+protocol+".class");
- if (_className != null) {
- if (debug) {
- System.out.println("DEBUG: mail."+protocol+
- ".class property exists and points to " +
- _className);
- }
- _provider = (Provider)providersByClassName.get(_className);
- }
-
- if (_provider != null) {
- return _provider;
- } else {
- // returning currently default protocol in providersByProtocol
- _provider = (Provider)providersByProtocol.get(protocol);
- }
-
- if (_provider == null) {
- throw new NoSuchProviderException("No provider for " + protocol);
- } else {
- if (debug) {
- System.out.println("\nDEBUG: getProvider() returning " +
- _provider.toString());
- }
- return _provider;
- }
- }
-
- /**
- * Set the passed Provider to be the default implementation
- * for the protocol in Provider.protocol overriding any previous values.
- *
- * @param provider Currently configured Provider which will be
- * set as the default for the protocol
- * @exception NoSuchProviderException If the provider passed in
- * is invalid.
- */
- public void setProvider(Provider provider) throws NoSuchProviderException {
- if (provider == null) {
- throw new NoSuchProviderException("Can't set null provider");
- }
- providersByProtocol.put(provider.getProtocol(), provider);
- props.put("mail." + provider.getProtocol() + ".class",
- provider.getClassName());
- }
-
-
- /**
- * Get a Store object that implements this user's desired Store
- * protocol. The <code>mail.store.protocol</code> property specifies the
- * desired protocol. If an appropriate Store object is not obtained,
- * NoSuchProviderException is thrown
- *
- * @return a Store object
- * @exception NoSuchProviderException If a provider for the given
- * protocol is not found.
- */
- public Store getStore() throws NoSuchProviderException {
- return getStore(getProperty("mail.store.protocol"));
- }
-
- /**
- * Get a Store object that implements the specified protocol. If an
- * appropriate Store object cannot be obtained,
- * NoSuchProviderException is thrown.
- *
- * @param protocol
- * @return a Store object
- * @exception NoSuchProviderException If a provider for the given
- * protocol is not found.
- */
- public Store getStore(String protocol) throws NoSuchProviderException {
- return getStore(new URLName(protocol, null, -1, null, null, null));
- }
-
-
- /**
- * Get a Store object for the given URLName. If the requested Store
- * object cannot be obtained, NoSuchProviderException is thrown.
- *
- * The "scheme" part of the URL string (Refer RFC 1738) is used
- * to locate the Store protocol. <p>
- *
- * @param url URLName that represents the desired Store
- * @return a closed Store object
- * @see #getFolder(URLName)
- * @see javax.mail.URLName
- * @exception NoSuchProviderException If a provider for the given
- * URLName is not found.
- */
- public Store getStore(URLName url) throws NoSuchProviderException {
- String protocol = url.getProtocol();
- Provider p = getProvider(protocol);
- return getStore(p, url);
- }
-
- /**
- * Get an instance of the store specified by Provider. Instantiates
- * the store and returns it.
- *
- * @param provider Store Provider that will be instantiated
- * @return Instantiated Store
- * @exception NoSuchProviderException If a provider for the given
- * Provider is not found.
- */
- public Store getStore(Provider provider) throws NoSuchProviderException {
- return getStore(provider, null);
- }
-
-
- /**
- * Get an instance of the store specified by Provider. If the URLName
- * is not null, uses it, otherwise creates a new one. Instantiates
- * the store and returns it. This is a private method used by
- * getStore(Provider) and getStore(URLName)
- *
- * @param provider Store Provider that will be instantiated
- * @param url URLName used to instantiate the Store
- * @return Instantiated Store
- * @exception NoSuchProviderException If a provider for the given
- * Provider/URLName is not found.
- */
- private Store getStore(Provider provider, URLName url)
- throws NoSuchProviderException {
-
- // make sure we have the correct type of provider
- if (provider == null || provider.getType() != Provider.Type.STORE ) {
- throw new NoSuchProviderException("invalid provider");
- }
-
- try {
- return (Store) getService(provider, url);
- } catch (ClassCastException cce) {
- throw new NoSuchProviderException("incorrect class");
- }
- }
-
- /**
- * Get a closed Folder object for the given URLName. If the requested
- * Folder object cannot be obtained, null is returned. <p>
- *
- * The "scheme" part of the URL string (Refer RFC 1738) is used
- * to locate the Store protocol. The rest of the URL string (that is,
- * the "schemepart", as per RFC 1738) is used by that Store
- * in a protocol dependent manner to locate and instantiate the
- * appropriate Folder object. <p>
- *
- * Note that RFC 1738 also specifies the syntax for the
- * "schemepart" for IP-based protocols (IMAP4, POP3, etc.).
- * Providers of IP-based mail Stores should implement that
- * syntax for referring to Folders. <p>
- *
- * @param url URLName that represents the desired folder
- * @return Folder
- * @see #getStore(URLName)
- * @see javax.mail.URLName
- * @exception NoSuchProviderException If a provider for the given
- * URLName is not found.
- * @exception MessagingException if the Folder could not be
- * located or created.
- */
- public Folder getFolder(URLName url)
- throws MessagingException {
- // First get the Store
- Store store = getStore(url);
- store.connect();
- return store.getFolder(url);
- }
-
- /**
- * Get a Transport object that implements this user's desired
- * Transport protcol. The <code>mail.transport.protocol</code> property
- * specifies the desired protocol. If an appropriate Transport
- * object cannot be obtained, MessagingException is thrown.
- *
- * @return a Transport object
- * @exception NoSuchProviderException If the provider is not found.
- */
- public Transport getTransport() throws NoSuchProviderException {
- return getTransport(getProperty("mail.transport.protocol"));
- }
-
- /**
- * Get a Transport object that implements the specified protocol.
- * If an appropriate Transport object cannot be obtained, null is
- * returned.
- *
- * @return a Transport object
- * @exception NoSuchProviderException If provider for the given
- * protocol is not found.
- */
- public Transport getTransport(String protocol)
- throws NoSuchProviderException {
- return getTransport(new URLName(protocol, null, -1, null, null, null));
- }
-
-
- /**
- * Get a Transport object for the given URLName. If the requested
- * Transport object cannot be obtained, NoSuchProviderException is thrown.
- *
- * The "scheme" part of the URL string (Refer RFC 1738) is used
- * to locate the Transport protocol. <p>
- *
- * @param url URLName that represents the desired Transport
- * @return a closed Transport object
- * @see javax.mail.URLName
- * @exception NoSuchProviderException If a provider for the given
- * URLName is not found.
- */
- public Transport getTransport(URLName url) throws NoSuchProviderException {
- String protocol = url.getProtocol();
- Provider p = getProvider(protocol);
- return getTransport(p, url);
- }
-
- /**
- * Get an instance of the transport specified in the Provider. Instantiates
- * the transport and returns it.
- *
- * @param provider Transport Provider that will be instantiated
- * @return Instantiated Transport
- * @exception NoSuchProviderException If provider for the given
- * provider is not found.
- */
- public Transport getTransport(Provider provider)
- throws NoSuchProviderException {
- return getTransport(provider, null);
- }
-
- /**
- * Get a Transport object that can transport a Message to the
- * specified address type.
- *
- * @param address
- * @return A Transport object
- * @see javax.mail.Address
- * @exception NoSuchProviderException If provider for the
- * Address type is not found
- */
- public Transport getTransport(Address address)
- throws NoSuchProviderException {
-
- String transportProtocol = (String)addressMap.get(address.getType());
- if (transportProtocol == null) {
- throw new NoSuchProviderException("No provider for Address type: "+
- address.getType());
- } else {
- return getTransport(transportProtocol);
- }
- }
-
- /**
- * Get a Transport object using the given provider and urlname.
- *
- * @param provider the provider to use
- * @param url urlname to use (can be null)
- * @return A Transport object
- * @exception NoSuchProviderException If no provider or the provider
- * was the wrong class.
- */
-
- private Transport getTransport(Provider provider, URLName url)
- throws NoSuchProviderException {
- // make sure we have the correct type of provider
- if (provider == null || provider.getType() != Provider.Type.TRANSPORT) {
- throw new NoSuchProviderException("invalid provider");
- }
-
- try {
- return (Transport) getService(provider, url);
- } catch (ClassCastException cce) {
- throw new NoSuchProviderException("incorrect class");
- }
- }
-
- /**
- * Get a Service object. Needs a provider object, but will
- * create a URLName if needed. It attempts to instantiate
- * the correct class.
- *
- * @param provider which provider to use
- * @param url which URLName to use (can be null)
- * @exception NoSuchProviderException thrown when the class cannot be
- * found or when it does not have the correct constructor
- * (Session, URLName), or if it is not derived from
- * Service.
- */
- private Object getService(Provider provider, URLName url)
- throws NoSuchProviderException {
- // need a provider and url
- if (provider == null) {
- throw new NoSuchProviderException("null");
- }
-
- // create a url if needed
- if (url == null) {
- url = new URLName(provider.getProtocol(), null, -1,
- null, null, null);
- }
-
- Object service = null;
-
- // get the ClassLoader associated with the Authenticator
- ClassLoader cl;
- if (authenticator != null)
- cl = authenticator.getClass().getClassLoader();
- else
- cl = this.getClass().getClassLoader();
-
- // now load the class
- Class serviceClass = null;
- try {
- // First try the "application's" class loader.
- // This should eventually be replaced by
- // Thread.currentThread().getContextClassLoader().
- serviceClass = cl.loadClass(provider.getClassName());
- } catch (Exception ex1) {
- // That didn't work, now try the "system" class loader.
- // (Need both of these because JDK 1.1 class loaders
- // may not delegate to their parent class loader.)
- try {
- serviceClass = Class.forName(provider.getClassName());
- } catch (Exception ex) {
- // Nothing worked, give up.
- if (debug) ex.printStackTrace();
- throw new NoSuchProviderException(provider.getProtocol());
- }
- }
-
- // construct an instance of the class
- try {
- Class[] c = {javax.mail.Session.class, javax.mail.URLName.class};
- Constructor cons = serviceClass.getConstructor(c);
-
- Object[] o = {this, url};
- service = cons.newInstance(o);
-
- } catch (Exception ex) {
- if (debug) ex.printStackTrace();
- throw new NoSuchProviderException(provider.getProtocol());
- }
-
- return service;
- }
-
- /**
- * Save a PasswordAuthentication for this (store or transport) URLName.
- * If pw is null the entry corresponding to the URLName is removed.
- * <p>
- * This is normally used only by the store or transport implementations
- * to allow authentication information to be shared among multiple
- * uses of a session.
- */
- public void setPasswordAuthentication(URLName url,
- PasswordAuthentication pw) {
- if (pw == null)
- authTable.remove(url);
- else
- authTable.put(url, pw);
- }
-
- /**
- * Return any saved PasswordAuthentication for this (store or transport)
- * URLName. Normally used only by store or transport implementations.
- *
- * @return the PasswordAuthentication corresponding to the URLName
- */
- public PasswordAuthentication getPasswordAuthentication(URLName url) {
- return (PasswordAuthentication)authTable.get(url);
- }
-
- /**
- * Call back to the application to get the needed user name and password.
- * The application should put up a dialog something like:
- * <p> <pre>
- * Connecting to <protocol> mail service on host <addr>, port <port>.
- * <prompt>
- *
- * User Name: <defaultUserName>
- * Password:
- * </pre>
- *
- * @param addr InetAddress of the host. may be null.
- * @param protocol protocol scheme (e.g. imap, pop3, etc.)
- * @param prompt any additional String to show as part of
- * the prompt; may be null.
- * @param defaultUserName the default username. may be null.
- * @return the authentication which was collected by the authenticator;
- * may be null.
- */
- public PasswordAuthentication requestPasswordAuthentication(
- InetAddress addr, int port,
- String protocol, String prompt, String defaultUserName) {
-
- if (authenticator != null) {
- return authenticator.requestPasswordAuthentication(
- addr, port, protocol, prompt, defaultUserName);
- } else {
- return null;
- }
- }
-
- /**
- * Returns the Properties object associated with this Session
- *
- * @return Properties object
- */
- public Properties getProperties() {
- return props;
- }
-
- /**
- * Returns the value of the specified property. Returns null
- * if this property does not exist.
- *
- * @return String that is the property value
- */
- public String getProperty(String name) {
- return props.getProperty(name);
- }
-
- private void loadProviders(Class cl) {
- // load system-wide javamail.providers from the <java.home>/lib dir
- // since we have an absolute path to the file, use FileInputStream
- InputStream javahomeProviderStream = null;
- try {
- String res = System.getProperty("java.home") +
- File.separator + "lib" +
- File.separator + "javamail.providers";
- javahomeProviderStream =
- new BufferedInputStream(new FileInputStream(res));
- if (javahomeProviderStream != null) {
- loadProvidersFromStream(javahomeProviderStream);
- javahomeProviderStream.close();
- if (debug)
- pr("DEBUG: loaded providers in <java.home>/lib");
- } else {
- if (debug)
- pr("DEBUG: not loading system providers in <java.home>/lib");
- }
- } catch (FileNotFoundException fex) { /*ignore: don't load resource*/
- if (debug)
- pr("DEBUG: not loading system providers in <java.home>/lib");
- } catch (IOException ioex) { /*ignore: don't load resource*/
- if (debug)
- pr("DEBUG: " + ioex.getMessage());
- } catch (SecurityException sex) { /*ignore: don't load resource*/
- if (debug)
- pr("DEBUG: not loading system providers in <java.home>/lib");
- }
-
- // load the META-INF/javamail.providers file supplied by an application
- // first try loading the resource file using the app classloader
- // if it fails, try loading it as system res.
- InputStream appProviderStream = null;
- final String clappRes = "META-INF/javamail.providers";
- final String appRes = "/" + clappRes;
- boolean anyLoaded = false;
-
- if (getResources != null) {
- try {
- Enumeration e;
- ClassLoader cld = cl.getClassLoader();
- if (cld != null)
- e = (Enumeration)getResources.invoke(
- cld, new String[] { clappRes });
- else
- e = (Enumeration)getSystemResources.invoke(
- cld, new String[] { clappRes });
- while (e.hasMoreElements()) {
- URL url = (URL)e.nextElement();
- appProviderStream = url.openStream();
- if (appProviderStream != null) {
- try {
- loadProvidersFromStream(appProviderStream);
- anyLoaded = true;
- appProviderStream.close();
- if (debug)
- pr("DEBUG: successfully loaded " +
- "optional custom providers from URL: " +
- url);
- } catch (IOException ioex) {
- if (debug)
- pr("DEBUG: " + ioex.getMessage());
- }
- } else {
- if (debug)
- pr("DEBUG: not loading optional custom providers " +
- "from URL: " + url);
- }
- }
- } catch (Exception ex) {
- if (debug)
- pr("DEBUG: " + ex);
- }
- }
-
- // if failed to load anything, fall back to old technique, just in case
- if (!anyLoaded) {
- appProviderStream = cl.getResourceAsStream(appRes);
- if (appProviderStream != null) {
- try {
- loadProvidersFromStream(appProviderStream);
- appProviderStream.close();
- if (debug)
- pr("DEBUG: successfully loaded " +
- "optional custom providers: " + appRes);
- } catch (IOException ioex) {
- if (debug)
- pr("DEBUG: " + ioex);
- }
- } else {
- if (debug)
- pr("DEBUG: not loading optional custom providers file: " +
- appRes);
- }
- }
-
- // load default META-INF/javamail.default.providers from mail.jar file
- InputStream defProviderStream = null;
- String defRes = "/META-INF/javamail.default.providers";
- defProviderStream = cl.getResourceAsStream(defRes);
- if (defProviderStream != null) {
- try {
- loadProvidersFromStream(defProviderStream);
- defProviderStream.close();
- if (debug)
- pr("DEBUG: successfully loaded default providers");
- } catch (IOException ioex) {
- if (debug)
- pr("DEBUG: " + ioex.getMessage());
- }
- } else {
- if (debug)
- pr("DEBUG: can't load default providers file" + defRes);
- }
-
-
- if (debug) {
- System.out.println("\nDEBUG: Tables of loaded providers");
- // dump the output of the tables for debugging
- //pr("DEBUG: --- Providers Listed By Class Name --------");
- //System.out.println("size " + providersByClassName.size());
- pr("DEBUG: Providers Listed By Class Name: " +
- providersByClassName.toString());
-
- //pr("\nDEBUG: --- Providers Listed By Protocol ---------");
- //System.out.println("size " + providersByProtocol.size());
- pr("DEBUG: Providers Listed By Protocol: " +
- providersByProtocol.toString());
- }
- }
-
- private void loadProvidersFromStream(InputStream is)
- throws IOException {
- if (is != null) {
- LineInputStream lis = new LineInputStream(is);
- String currLine;
-
- // load and process one line at a time using LineInputStream
- while ((currLine = lis.readLine()) != null) {
-
- if (currLine.startsWith("#"))
- continue;
- Provider.Type type = null;
- String protocol = null, className = null;
- String vendor = null, version = null;
-
- // separate line into key-value tuples
- StringTokenizer tuples = new StringTokenizer(currLine,";");
- while (tuples.hasMoreTokens()) {
- String currTuple = tuples.nextToken().trim();
-
- // set the value of each attribute based on its key
- int sep = currTuple.indexOf("=");
- if (currTuple.startsWith("protocol=")) {
- protocol = currTuple.substring(sep+1);
- } else if (currTuple.startsWith("type=")) {
- String strType = currTuple.substring(sep+1);
- if (strType.equalsIgnoreCase("store")) {
- type = Provider.Type.STORE;
- } else if (strType.equalsIgnoreCase("transport")) {
- type = Provider.Type.TRANSPORT;
- }
- } else if (currTuple.startsWith("class=")) {
- className = currTuple.substring(sep+1);
- } else if (currTuple.startsWith("vendor=")) {
- vendor = currTuple.substring(sep+1);
- } else if (currTuple.startsWith("version=")) {
- version = currTuple.substring(sep+1);
- }
- }
-
- // check if a valid Provider; else, continue
- if (type == null || protocol == null || className == null
- || protocol.length() <= 0 || className.length() <= 0) {
-
- if (debug)
- System.out.println("DEBUG: Bad provider entry: " +
- currLine);
- continue;
- }
- Provider provider = new Provider(type, protocol, className,
- vendor, version);
-
- // add the newly-created Provider to the lookup tables
- providers.addElement(provider);
- providersByClassName.put(className, provider);
- if (!providersByProtocol.containsKey(protocol)) {
- providersByProtocol.put(protocol, provider);
- }
- }
- }
- }
-
- // load maps in reverse order of preference so that the preferred
- // map is loaded last since its entries will override the previous ones
- private void loadAddressMap(Class cl) {
- // load default META-INF/javamail.default.address.map from mail.jar
- // first try loading the resource file using the app classloader
- // if it fails, try loading it as system res.
- InputStream defAddressStream = null;
- String defRes = "/META-INF/javamail.default.address.map";
- defAddressStream = cl.getResourceAsStream(defRes);
- if (defAddressStream != null) {
- try {
- addressMap.load(defAddressStream);
- defAddressStream.close();
- } catch (IOException ioex) { /* ignore it */
- } catch (SecurityException sex) { /* ignore it */ }
- }
-
- // load the META-INF/javamail.address.map file supplied by an app
- // first try loading the resource file using the app classloader
- // if it fails, try loading it as system res.
- InputStream appAddressStream = null;
- final String clappRes = "META-INF/javamail.address.map";
- final String appRes = "/" + clappRes;
- boolean anyLoaded = false;
-
- if (getResources != null) {
- try {
- Enumeration e;
- ClassLoader cld = cl.getClassLoader();
- if (cld != null)
- e = (Enumeration)getResources.invoke(
- cld, new String[] { clappRes });
- else
- e = (Enumeration)getSystemResources.invoke(
- cld, new String[] { clappRes });
- while (e.hasMoreElements()) {
- URL url = (URL)e.nextElement();
- appAddressStream = url.openStream();
- if (appAddressStream != null) {
- try {
- addressMap.load(appAddressStream);
- anyLoaded = true;
- appAddressStream.close();
- if (debug)
- pr("DEBUG: successfully loaded " +
- "optional address map from URL: " + url);
- } catch (IOException ioex) {
- if (debug)
- pr("DEBUG: " + ioex.getMessage());
- }
- } else {
- if (debug)
- pr("DEBUG: not loading optional address map " +
- "from URL: " + url);
- }
- }
- } catch (Exception ex) {
- if (debug)
- pr("DEBUG: " + ex);
- }
- }
-
- // if failed to load anything, fall back to old technique, just in case
- if (!anyLoaded) {
- appAddressStream = cl.getResourceAsStream(appRes);
- if (appAddressStream != null) {
- try {
- addressMap.load(appAddressStream);
- appAddressStream.close();
- if (debug)
- pr("DEBUG: successfully loaded " +
- "optional address map: " + appRes);
- } catch (IOException ioex) {
- if (debug)
- pr("DEBUG: " + ioex);
- }
- } else {
- if (debug)
- pr("DEBUG: not loading optional address map file: " +
- appRes);
- }
- }
-
-
- // load system-wide javamail.address.map from the <java.home>/lib dir
- // since we have an absolute path to the file, use FileInputStream
- InputStream javahomeAddressStream = null;
- try {
- String res = System.getProperty("java.home") +
- File.separator + "lib" +
- File.separator + "javamail.address.map";
- javahomeAddressStream =
- new BufferedInputStream(new FileInputStream(res));
- } catch (FileNotFoundException fex) {
- /*ignore: don't load resource*/
- } catch (SecurityException sex) {
- /*ignore: don't load resource*/
- }
- if (javahomeAddressStream != null) {
- try {
- addressMap.load(javahomeAddressStream);
- javahomeAddressStream.close();
- } catch (IOException ioex) { /* ignore it */ }
- }
- }
-
- private static void pr(String str) {
- System.out.println(str);
- }
- }