1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/*
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2009 Mike Cumings
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Licensed under the Apache License, Version 2.0 (the "License");
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License.
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *   http://www.apache.org/licenses/LICENSE-2.0
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS,
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License.
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage com.kenai.jbosh;
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.net.URI;
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport javax.net.ssl.SSLContext;
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * BOSH client configuration information.  Instances of this class contain
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * all information necessary to establish connectivity with a remote
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * connection manager.
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/>
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Instances of this class are immutable, thread-safe,
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * and can be re-used to configure multiple client session instances.
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic final class BOSHClientConfig {
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Connection manager URI.
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final URI uri;
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Target domain.
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final String to;
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Client ID of this station.
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final String from;
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Default XML language.
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final String lang;
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Routing information for messages sent to CM.
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final String route;
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Proxy host.
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final String proxyHost;
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Proxy port.
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final int proxyPort;
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * SSL context.
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final SSLContext sslContext;
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Flag indicating that compression should be attempted, if possible.
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private final boolean compressionEnabled;
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // Classes:
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Class instance builder, after the builder pattern.  This allows each
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * {@code BOSHClientConfig} instance to be immutable while providing
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * flexibility when building new {@code BOSHClientConfig} instances.
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Instances of this class are <b>not</b> thread-safe.  If template-style
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * use is desired, see the {@code create(BOSHClientConfig)} method.
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static final class Builder {
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Required args
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private final URI bURI;
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private final String bDomain;
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Optional args
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private String bFrom;
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private String bLang;
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private String bRoute;
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private String bProxyHost;
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private int bProxyPort;
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private SSLContext bSSLContext;
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private Boolean bCompression;
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Creates a new builder instance, used to create instances of the
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * {@code BOSHClientConfig} class.
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param cmURI URI to use to contact the connection manager
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param domain target domain to communicate with
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private Builder(final URI cmURI, final String domain) {
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bURI = cmURI;
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bDomain = domain;
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Creates a new builder instance, used to create instances of the
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * {@code BOSHClientConfig} class.
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param cmURI URI to use to contact the connection manager
119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param domain target domain to communicate with
120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public static Builder create(final URI cmURI, final String domain) {
123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (cmURI == null) {
124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Connection manager URI must not be null"));
126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (domain == null) {
128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Target domain must not be null"));
130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String scheme = cmURI.getScheme();
132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!("http".equals(scheme) || "https".equals(scheme))) {
133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Only 'http' and 'https' URI are allowed"));
135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return new Builder(cmURI, domain);
137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Creates a new builder instance using the existing configuration
141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * provided as a starting point.
142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param cfg configuration to copy
144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public static Builder create(final BOSHClientConfig cfg) {
147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            Builder result = new Builder(cfg.getURI(), cfg.getTo());
148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bFrom = cfg.getFrom();
149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bLang = cfg.getLang();
150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bRoute = cfg.getRoute();
151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bProxyHost = cfg.getProxyHost();
152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bProxyPort = cfg.getProxyPort();
153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bSSLContext = cfg.getSSLContext();
154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            result.bCompression = cfg.isCompressionEnabled();
155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return result;
156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Set the ID of the client station, to be forwarded to the connection
160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * manager when new sessions are created.
161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param id client ID
163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public Builder setFrom(final String id) {
166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (id == null) {
167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Client ID must not be null"));
169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bFrom = id;
171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return this;
172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Set the default language of any human-readable content within the
176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * XML.
177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param lang XML language ID
179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public Builder setXMLLang(final String lang) {
182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (lang == null) {
183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Default language ID must not be null"));
185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bLang = lang;
187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return this;
188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Sets the destination server/domain that the client should connect to.
192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Connection managers may be configured to enable sessions with more
193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * that one server in different domains.  When requesting a session with
194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * such a "proxy" connection manager, a client should use this method to
195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * specify the server with which it wants to communicate.
196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param protocol connection protocol (e.g, "xmpp")
198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param host host or domain to be served by the remote server.  Note
199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *  that this is not necessarily the host name or domain name of the
200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *  remote server.
201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param port port number of the remote server
202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public Builder setRoute(
205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                final String protocol,
206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                final String host,
207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                final int port) {
208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (protocol == null) {
209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException("Protocol cannot be null"));
210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (protocol.contains(":")) {
212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Protocol cannot contain the ':' character"));
214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (host == null) {
216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException("Host cannot be null"));
217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (host.contains(":")) {
219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Host cannot contain the ':' character"));
221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (port <= 0) {
223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException("Port number must be > 0"));
224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bRoute = protocol + ":" + host + ":" + port;
226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return this;
227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Specify the hostname and port of an HTTP proxy to connect through.
231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param hostName proxy hostname
233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param port proxy port number
234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public Builder setProxy(final String hostName, final int port) {
237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (hostName == null || hostName.length() == 0) {
238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Proxy host name cannot be null or empty"));
240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (port <= 0) {
242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "Proxy port must be > 0"));
244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bProxyHost = hostName;
246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bProxyPort = port;
247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return this;
248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Set the SSL context to use for this session.  This can be used
252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * to configure certificate-based authentication, etc..
253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param ctx SSL context
255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public Builder setSSLContext(final SSLContext ctx) {
258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (ctx == null) {
259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw(new IllegalArgumentException(
260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        "SSL context cannot be null"));
261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bSSLContext = ctx;
263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return this;
264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Set whether or not compression of the underlying data stream
268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * should be attempted.  By default, compression is disabled.
269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @param enabled set to {@code true} if compression should be
271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *  attempted when possible, {@code false} to disable compression
272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return builder instance
273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public Builder setCompressionEnabled(final boolean enabled) {
275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            bCompression = Boolean.valueOf(enabled);
276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return this;
277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Build the immutable object instance with the current configuration.
281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         *
282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * @return BOSHClientConfig instance
283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public BOSHClientConfig build() {
285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Default XML language
286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String lang;
287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (bLang == null) {
288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                lang = "en";
289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            } else {
290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                lang = bLang;
291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Default proxy port
294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            int port;
295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (bProxyHost == null) {
296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                port = 0;
297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            } else {
298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                port = bProxyPort;
299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Default compression
302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            boolean compression;
303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (bCompression == null) {
304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                compression = false;
305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            } else {
306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                compression = bCompression.booleanValue();
307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return new BOSHClientConfig(
310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    bURI,
311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    bDomain,
312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    bFrom,
313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    lang,
314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    bRoute,
315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    bProxyHost,
316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    port,
317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    bSSLContext,
318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    compression);
319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    ///////////////////////////////////////////////////////////////////////////
324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // Constructor:
325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Prevent direct construction.
328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cURI URI of the connection manager to connect to
330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cDomain the target domain of the first stream
331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cFrom client ID
332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cLang default XML language
333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cRoute target route
334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cProxyHost proxy host
335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cProxyPort proxy port
336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cSSLContext SSL context
337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param cCompression compression enabled flag
338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private BOSHClientConfig(
340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final URI cURI,
341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final String cDomain,
342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final String cFrom,
343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final String cLang,
344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final String cRoute,
345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final String cProxyHost,
346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final int cProxyPort,
347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final SSLContext cSSLContext,
348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            final boolean cCompression) {
349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        uri = cURI;
350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        to = cDomain;
351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        from = cFrom;
352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        lang = cLang;
353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        route = cRoute;
354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        proxyHost = cProxyHost;
355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        proxyPort = cProxyPort;
356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        sslContext = cSSLContext;
357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        compressionEnabled = cCompression;
358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the URI to use to contact the connection manager.
362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return connection manager URI.
364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public URI getURI() {
366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return uri;
367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the ID of the target domain.
371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return domain id
373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getTo() {
375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return to;
376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the ID of the local client.
380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return client id, or {@code null}
382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getFrom() {
384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return from;
385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the default language of any human-readable content within the
389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * XML.  Defaults to "en".
390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return XML language ID
392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getLang() {
394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return lang;
395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the routing information for messages sent to the CM.
399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return route attribute string, or {@code null} if no routing
401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  info was provided.
402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getRoute() {
404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return route;
405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the HTTP proxy host to use.
409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return proxy host, or {@code null} if no proxy information was specified
411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getProxyHost() {
413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return proxyHost;
414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the HTTP proxy port to use.
418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return proxy port, or 0 if no proxy information was specified
420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int getProxyPort() {
422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return proxyPort;
423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Get the SSL context to use for this session.
427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return SSL context instance to use, or {@code null} if no
429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  context instance was provided.
430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public SSLContext getSSLContext() {
432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return sslContext;
433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Determines whether or not compression of the underlying data stream
437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * should be attempted/allowed.  Defaults to {@code false}.
438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return {@code true} if compression should be attempted, {@code false}
440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *  if compression is disabled or was not specified
441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    boolean isCompressionEnabled() {
443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return compressionEnabled;
444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
447