protected void getConnectedSSLSocket()

in geronimo-javamail_1.3.1/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java [292:418]


	protected void getConnectedSSLSocket() throws IOException {

	    if (session.getDebug()) {
	        session.getDebugOut().println("Attempting SSL socket connection to server " + host + ":" + port);
	    }
	    // the socket factory can be specified via a protocol property, a
	    // session property, and if all else
	    // fails (which it usually does), we fall back to the standard factory
	    // class.
	    String socketFactory = getProtocolProperty(MAIL_POP3_FACTORY_CLASS, getSessionProperty(MAIL_SSLFACTORY_CLASS,
	            "javax.net.ssl.SSLSocketFactory"));
	
	    // there are several protocol properties that can be set to tune the
	    // created socket. We need to
	    // retrieve those bits before creating the socket.
	    int timeout = getIntProtocolProperty(MAIL_POP3_TIMEOUT, -1);
	    InetAddress localAddress = null;
	    // see if we have a local address override.
	    String localAddrProp = getProtocolProperty(MAIL_POP3_LOCALADDRESS);
	    if (localAddrProp != null) {
	        localAddress = InetAddress.getByName(localAddrProp);
	    }
	
	    // check for a local port...default is to allow socket to choose.
	    int localPort = getIntProtocolProperty(MAIL_POP3_LOCALPORT, 0);
	
	    socket = null;
	
	    // if there is no socket factory defined (normal), we just create a
	    // socket directly.
	    if (socketFactory == null) {
	    	System.out.println("SocketFactory was null so creating the connection using a default");
	        socket = new Socket(host, port, localAddress, localPort);
	    }
	
	    else {
	        // we'll try this with potentially two different factories if we're
	        // allowed to fall back.
	        boolean fallback = isProtocolPropertyTrue(MAIL_POP3_FACTORY_FALLBACK);
	        while(true) {
	            try {
	            	
	            	
	            	if (socket != null) {
	            		if (socket.isConnected())
	            		break;
	            	}
	            	
	                if (session.getDebug()) {
	                    session.getDebugOut().println("Creating SSL socket using factory " + socketFactory);
	                }
	                
	                int socketFactoryPort = getIntProtocolProperty(MAIL_POP3_FACTORY_PORT, -1);
	
	                // we choose the port used by the socket based on overrides.
	                Integer portArg = new Integer(socketFactoryPort == -1 ? port : socketFactoryPort);
	
	                // use the current context loader to resolve this.
	                ClassLoader loader = Thread.currentThread().getContextClassLoader();
	                Class factoryClass = loader.loadClass(socketFactory);
	
	                // done indirectly, we need to invoke the method using
	                // reflection.
	                // This retrieves a factory instance.
	                Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
	                Object defFactory = getDefault.invoke(new Object(), new Object[0]);
	
	                // now that we have the factory, there are two different
	                // createSocket() calls we use,
	                // depending on whether we have a localAddress override.
	
	                if (localAddress != null) {
	                    // retrieve the createSocket(String, int, InetAddress,
	                    // int) method.
	                    Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class,
	                            Integer.TYPE };
	                    Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
	
	                    Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
	                    socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
	                } else {
	                    // retrieve the createSocket(String, int) method.
	                    Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
	                    Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
	
	                    Object[] createSocketArgs = new Object[] { host, portArg };
	                    socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
	                }
	            } catch (Throwable e) {
	                // if we're allowed to fallback, then use the default
	                // factory and try this again. We only
	                // allow this to happen once.
                    if (session.getDebug()) {
                        session.getDebugOut().println("First attempt at creating SSL socket failed, falling back to default factory");
                    }
	                if (fallback) {
	                    socketFactory = "javax.net.ssl.SSLSocketFactory";
	                    fallback = false;
	                    continue;
	                }
	                // we have an exception. We're going to throw an
	                // IOException, which may require unwrapping
	                // or rewrapping the exception.
	                else {
	                    // we have an exception from the reflection, so unwrap
	                    // the base exception
	                    if (e instanceof InvocationTargetException) {
	                        e = ((InvocationTargetException) e).getTargetException();
	                    }
	
	                    if (session.getDebug()) {
	                        session.getDebugOut().println("Failure creating SSL socket: " + e);
	                    }
	                    // throw this as an IOException, with the original
	                    // exception attached.
	                    IOException ioe = new IOException("Error connecting to " + host + ", " + port);
	                    ioe.initCause(e);
	                    throw ioe;
	                }
	            }
	        }
	    }
	
	    if (timeout >= 0) {
	        socket.setSoTimeout(timeout);
	    }
	}