public void getConnectedSocket()

in geronimo-javamail_1.3.1/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java [294:399]


    public void getConnectedSocket() throws IOException {
        if (debug) {
            debugOut("Attempting plain socket connection to server " + host + ":" + port);
        }

        // the socket factory can be specified via a session property. By
        // default, we just directly
        // instantiate a socket without using a factor.
        String socketFactory = getProperty(MAIL_NNTP_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 = getIntProperty(MAIL_NNTP_TIMEOUT, -1);
        InetAddress localAddress = null;
        // see if we have a local address override.
        String localAddrProp = getProperty(MAIL_NNTP_LOCALADDRESS);
        if (localAddrProp != null) {
            localAddress = InetAddress.getByName(localAddrProp);
        }

        // check for a local port...default is to allow socket to choose.
        int localPort = getIntProperty(MAIL_NNTP_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 = getIntProperty(MAIL_NNTP_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 factor is specified, then we may need to fall
                // back to a default. This behavior
                // is controlled by (surprise) more session properties.
                if (getBooleanProperty(MAIL_NNTP_FACTORY_FALLBACK, false)) {
                    if (debug) {
                        debugOut("First plain socket attempt faile, falling back to default factory", e);
                    }
                    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();
                    }

                    if (debug) {
                        debugOut("Plain socket creation failure", 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);
        }
    }