src/main/java/org/jivesoftware/whack/ExternalComponent.java
public void connect(String host, int port, String subdomain)
            throws ComponentException {
        try {
            // Open a socket to the server
            this.socket = new Socket();
            socket.connect(new InetSocketAddress(host, port),
                    manager.getConnectTimeout());
            if (manager.getServerName() != null) {
                this.domain = subdomain + "." + manager.getServerName();
            } else {
                this.domain = subdomain;
            }
            this.subdomain = subdomain;
            // Keep these variables that will be used in case a reconnection is
            // required
            this.host = host;
            this.port = port;

            try {
                factory = XmlPullParserFactory.newInstance();
                reader = new XPPPacketReader();
                reader.setXPPFactory(factory);

                reader.getXPPParser()
                        .setInput(
                                new InputStreamReader(socket.getInputStream(),
                                        CHARSET));

                // Get a writer for sending the open stream tag
                writer = new BufferedWriter(new OutputStreamWriter(
                        socket.getOutputStream(), CHARSET));
                // Open the stream.
                StringBuilder stream = new StringBuilder();
                stream.append("<stream:stream");
                stream.append(" xmlns=\"jabber:component:accept\"");
                stream.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
                if (manager.isMultipleAllowed(subdomain)) {
                    stream.append(" allowMultiple=\"true\"");
                }
                stream.append(" to=\"").append(domain).append("\">");
                writer.write(stream.toString());
                writer.flush();
                stream = null;

                // Get the answer from the server
                XmlPullParser xpp = reader.getXPPParser();
                for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
                    eventType = xpp.next();
                }

                // Set the streamID returned from the server
                connectionID = xpp.getAttributeValue("", "id");
                if (xpp.getAttributeValue("", "from") != null) {
                    this.domain = xpp.getAttributeValue("", "from");
                }
                xmlSerializer = new XMLWriter(writer);

                // Handshake with the server
                stream = new StringBuilder();
                stream.append("<handshake>");
                stream.append(StringUtils.hash(connectionID
                        + manager.getSecretKey(subdomain)));
                stream.append("</handshake>");
                writer.write(stream.toString());
                writer.flush();
                stream = null;

                // Get the answer from the server
                try {
                    Element doc = reader.parseDocument().getRootElement();
                    if ("error".equals(doc.getName())) {
                        StreamError error = new StreamError(doc);
                        // Close the connection
                        socket.close();
                        socket = null;
                        // throw the exception with the wrapped error
                        throw new ComponentException(error);
                    }
                    // Everything went fine
                    // Start keep alive thread to send every 30 seconds of
                    // inactivity a heart beat
                    keepAliveTask = new KeepAliveTask();
                    TaskEngine.getInstance().scheduleAtFixedRate(keepAliveTask,
                            15000, 30000);

                    timeoutTask = new TimeoutTask();
                    TaskEngine.getInstance().scheduleAtFixedRate(timeoutTask,
                            2000, 2000);

                } catch (DocumentException e) {
                    try {
                        socket.close();
                    } catch (IOException ioe) {
                        // Do nothing
                    }
                    throw new ComponentException(e);
                } catch (XmlPullParserException e) {
                    try {
                        socket.close();
                    } catch (IOException ioe) {
                        // Do nothing
                    }
                    throw new ComponentException(e);
                }
            } catch (XmlPullParserException e) {
                try {
                    socket.close();
                } catch (IOException ioe) {
                    // Do nothing
                }
                throw new ComponentException(e);
            }
        } catch (UnknownHostException uhe) {
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                // Do nothing
            }
            throw new ComponentException(uhe);
        } catch (IOException ioe) {
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                // Do nothing
            }
            throw new ComponentException(ioe);
        }
    }
public void connect(String host, int port, String subdomain)
            throws ComponentException {
        try {
            // Open a socket to the server
            this.socket = new Socket();
            socket.connect(new InetSocketAddress(host, port),
                    manager.getConnectTimeout());
            if (manager.getServerName() != null) {
                this.domain = subdomain + "." + manager.getServerName();
            } else {
                this.domain = subdomain;
            }
            this.subdomain = subdomain;
            // Keep these variables that will be used in case a reconnection is
            // required
            this.host = host;
            this.port = port;

            try {
                factory = XmlPullParserFactory.newInstance();
                reader = new XPPPacketReader();
                reader.setXPPFactory(factory);

                reader.getXPPParser()
                        .setInput(
                                new InputStreamReader(socket.getInputStream(),
                                        CHARSET));

                // Get a writer for sending the open stream tag
                writer = new BufferedWriter(new OutputStreamWriter(
                        socket.getOutputStream(), CHARSET));
                // Open the stream.
                StringBuilder stream = new StringBuilder();
                stream.append("<stream:stream");
                stream.append(" xmlns=\"jabber:component:accept\"");
                stream.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
                if (manager.isMultipleAllowed(subdomain)) {
                    stream.append(" allowMultiple=\"true\"");
                }
                stream.append(" to=\"").append(domain).append("\">");
                writer.write(stream.toString());
                writer.flush();
                stream = null;

                // Get the answer from the server
                XmlPullParser xpp = reader.getXPPParser();
                for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
                    eventType = xpp.next();
                }

                // Set the streamID returned from the server
                connectionID = xpp.getAttributeValue("", "id");
                if (xpp.getAttributeValue("", "from") != null) {
                    this.domain = xpp.getAttributeValue("", "from");
                }
                xmlSerializer = new XMLWriter(writer);

                // Handshake with the server
                stream = new StringBuilder();
                stream.append("<handshake>");
                stream.append(StringUtils.hash(connectionID
                        + manager.getSecretKey(subdomain)));
                stream.append("</handshake>");
                writer.write(stream.toString());
                writer.flush();
                stream = null;

                // Get the answer from the server
                try {
                    Element doc = reader.parseDocument().getRootElement();
                    if ("error".equals(doc.getName())) {
                        StreamError error = new StreamError(doc);
                        // Close the connection
                        socket.close();
                        socket = null;
                        // throw the exception with the wrapped error
                        throw new ComponentException(error);
                    }
                    // Everything went fine
                    // Start keep alive thread to send every 30 seconds of
                    // inactivity a heart beat
                    keepAliveTask = new KeepAliveTask();
                    TaskEngine.getInstance().scheduleAtFixedRate(keepAliveTask,
                            15000, 30000);

                    timeoutTask = new TimeoutTask();
                    TaskEngine.getInstance().scheduleAtFixedRate(timeoutTask,
                            2000, 2000);

                } catch (DocumentException e) {
                    try {
                        socket.close();
                    } catch (IOException ioe) {
                        // Do nothing
                    }
                    throw new ComponentException(e);
                } catch (XmlPullParserException e) {
                    try {
                        socket.close();
                    } catch (IOException ioe) {
                        // Do nothing
                    }
                    throw new ComponentException(e);
                }
            } catch (XmlPullParserException e) {
                try {
                    socket.close();
                } catch (IOException ioe) {
                    // Do nothing
                }
                throw new ComponentException(e);
            }
        } catch (UnknownHostException uhe) {
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                // Do nothing
            }
            throw new ComponentException(uhe);
        } catch (IOException ioe) {
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                // Do nothing
            }
            throw new ComponentException(ioe);
        }
    }
Generates a connection with the server and tries to authenticate. If an
error occurs in any of the steps then a ComponentException is thrown.

@param host
the host to connect with.
@param port
the port to use.
@param subdomain
the subdomain that this component will be handling.
@throws ComponentException
if an error happens during the connection and authentication
steps.