protected void getConnectedSocket()

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


	protected void getConnectedSocket() throws IOException {
	
	    // the socket factory can be specified via a session property. By
	    // default, we just directly
	    // instantiate a socket without using a factor.
	    String socketFactory = getProtocolProperty(MAIL_POP3_FACTORY_CLASS);
	
	    // 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) {
	        socket = new Socket(host, port, localAddress, localPort);
	    }
	
	    else {
	        try {
	            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 a socket factory is specified, then we may need to fall
	            // back to a default. This behavior
	            // is controlled by (surprise) more session properties.
	            if (isProtocolPropertyTrue(MAIL_POP3_FACTORY_FALLBACK)) {
	                socket = new Socket(host, port, localAddress, localPort);
	            }
	            // 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();
	                }

	
	                // 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);
	    }
	}