diff options
Diffstat (limited to 'src/com/kenai/jbosh/BOSHClientConfig.java')
-rw-r--r-- | src/com/kenai/jbosh/BOSHClientConfig.java | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/src/com/kenai/jbosh/BOSHClientConfig.java b/src/com/kenai/jbosh/BOSHClientConfig.java new file mode 100644 index 0000000..23915b6 --- /dev/null +++ b/src/com/kenai/jbosh/BOSHClientConfig.java @@ -0,0 +1,446 @@ +/* + * Copyright 2009 Mike Cumings + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.kenai.jbosh; + +import java.net.URI; +import javax.net.ssl.SSLContext; + +/** + * BOSH client configuration information. Instances of this class contain + * all information necessary to establish connectivity with a remote + * connection manager. + * <p/> + * Instances of this class are immutable, thread-safe, + * and can be re-used to configure multiple client session instances. + */ +public final class BOSHClientConfig { + + /** + * Connection manager URI. + */ + private final URI uri; + + /** + * Target domain. + */ + private final String to; + + /** + * Client ID of this station. + */ + private final String from; + + /** + * Default XML language. + */ + private final String lang; + + /** + * Routing information for messages sent to CM. + */ + private final String route; + + /** + * Proxy host. + */ + private final String proxyHost; + + /** + * Proxy port. + */ + private final int proxyPort; + + /** + * SSL context. + */ + private final SSLContext sslContext; + + /** + * Flag indicating that compression should be attempted, if possible. + */ + private final boolean compressionEnabled; + + /////////////////////////////////////////////////////////////////////////// + // Classes: + + /** + * Class instance builder, after the builder pattern. This allows each + * {@code BOSHClientConfig} instance to be immutable while providing + * flexibility when building new {@code BOSHClientConfig} instances. + * <p/> + * Instances of this class are <b>not</b> thread-safe. If template-style + * use is desired, see the {@code create(BOSHClientConfig)} method. + */ + public static final class Builder { + // Required args + private final URI bURI; + private final String bDomain; + + // Optional args + private String bFrom; + private String bLang; + private String bRoute; + private String bProxyHost; + private int bProxyPort; + private SSLContext bSSLContext; + private Boolean bCompression; + + /** + * Creates a new builder instance, used to create instances of the + * {@code BOSHClientConfig} class. + * + * @param cmURI URI to use to contact the connection manager + * @param domain target domain to communicate with + */ + private Builder(final URI cmURI, final String domain) { + bURI = cmURI; + bDomain = domain; + } + + /** + * Creates a new builder instance, used to create instances of the + * {@code BOSHClientConfig} class. + * + * @param cmURI URI to use to contact the connection manager + * @param domain target domain to communicate with + * @return builder instance + */ + public static Builder create(final URI cmURI, final String domain) { + if (cmURI == null) { + throw(new IllegalArgumentException( + "Connection manager URI must not be null")); + } + if (domain == null) { + throw(new IllegalArgumentException( + "Target domain must not be null")); + } + String scheme = cmURI.getScheme(); + if (!("http".equals(scheme) || "https".equals(scheme))) { + throw(new IllegalArgumentException( + "Only 'http' and 'https' URI are allowed")); + } + return new Builder(cmURI, domain); + } + + /** + * Creates a new builder instance using the existing configuration + * provided as a starting point. + * + * @param cfg configuration to copy + * @return builder instance + */ + public static Builder create(final BOSHClientConfig cfg) { + Builder result = new Builder(cfg.getURI(), cfg.getTo()); + result.bFrom = cfg.getFrom(); + result.bLang = cfg.getLang(); + result.bRoute = cfg.getRoute(); + result.bProxyHost = cfg.getProxyHost(); + result.bProxyPort = cfg.getProxyPort(); + result.bSSLContext = cfg.getSSLContext(); + result.bCompression = cfg.isCompressionEnabled(); + return result; + } + + /** + * Set the ID of the client station, to be forwarded to the connection + * manager when new sessions are created. + * + * @param id client ID + * @return builder instance + */ + public Builder setFrom(final String id) { + if (id == null) { + throw(new IllegalArgumentException( + "Client ID must not be null")); + } + bFrom = id; + return this; + } + + /** + * Set the default language of any human-readable content within the + * XML. + * + * @param lang XML language ID + * @return builder instance + */ + public Builder setXMLLang(final String lang) { + if (lang == null) { + throw(new IllegalArgumentException( + "Default language ID must not be null")); + } + bLang = lang; + return this; + } + + /** + * Sets the destination server/domain that the client should connect to. + * Connection managers may be configured to enable sessions with more + * that one server in different domains. When requesting a session with + * such a "proxy" connection manager, a client should use this method to + * specify the server with which it wants to communicate. + * + * @param protocol connection protocol (e.g, "xmpp") + * @param host host or domain to be served by the remote server. Note + * that this is not necessarily the host name or domain name of the + * remote server. + * @param port port number of the remote server + * @return builder instance + */ + public Builder setRoute( + final String protocol, + final String host, + final int port) { + if (protocol == null) { + throw(new IllegalArgumentException("Protocol cannot be null")); + } + if (protocol.contains(":")) { + throw(new IllegalArgumentException( + "Protocol cannot contain the ':' character")); + } + if (host == null) { + throw(new IllegalArgumentException("Host cannot be null")); + } + if (host.contains(":")) { + throw(new IllegalArgumentException( + "Host cannot contain the ':' character")); + } + if (port <= 0) { + throw(new IllegalArgumentException("Port number must be > 0")); + } + bRoute = protocol + ":" + host + ":" + port; + return this; + } + + /** + * Specify the hostname and port of an HTTP proxy to connect through. + * + * @param hostName proxy hostname + * @param port proxy port number + * @return builder instance + */ + public Builder setProxy(final String hostName, final int port) { + if (hostName == null || hostName.length() == 0) { + throw(new IllegalArgumentException( + "Proxy host name cannot be null or empty")); + } + if (port <= 0) { + throw(new IllegalArgumentException( + "Proxy port must be > 0")); + } + bProxyHost = hostName; + bProxyPort = port; + return this; + } + + /** + * Set the SSL context to use for this session. This can be used + * to configure certificate-based authentication, etc.. + * + * @param ctx SSL context + * @return builder instance + */ + public Builder setSSLContext(final SSLContext ctx) { + if (ctx == null) { + throw(new IllegalArgumentException( + "SSL context cannot be null")); + } + bSSLContext = ctx; + return this; + } + + /** + * Set whether or not compression of the underlying data stream + * should be attempted. By default, compression is disabled. + * + * @param enabled set to {@code true} if compression should be + * attempted when possible, {@code false} to disable compression + * @return builder instance + */ + public Builder setCompressionEnabled(final boolean enabled) { + bCompression = Boolean.valueOf(enabled); + return this; + } + + /** + * Build the immutable object instance with the current configuration. + * + * @return BOSHClientConfig instance + */ + public BOSHClientConfig build() { + // Default XML language + String lang; + if (bLang == null) { + lang = "en"; + } else { + lang = bLang; + } + + // Default proxy port + int port; + if (bProxyHost == null) { + port = 0; + } else { + port = bProxyPort; + } + + // Default compression + boolean compression; + if (bCompression == null) { + compression = false; + } else { + compression = bCompression.booleanValue(); + } + + return new BOSHClientConfig( + bURI, + bDomain, + bFrom, + lang, + bRoute, + bProxyHost, + port, + bSSLContext, + compression); + } + + } + + /////////////////////////////////////////////////////////////////////////// + // Constructor: + + /** + * Prevent direct construction. + * + * @param cURI URI of the connection manager to connect to + * @param cDomain the target domain of the first stream + * @param cFrom client ID + * @param cLang default XML language + * @param cRoute target route + * @param cProxyHost proxy host + * @param cProxyPort proxy port + * @param cSSLContext SSL context + * @param cCompression compression enabled flag + */ + private BOSHClientConfig( + final URI cURI, + final String cDomain, + final String cFrom, + final String cLang, + final String cRoute, + final String cProxyHost, + final int cProxyPort, + final SSLContext cSSLContext, + final boolean cCompression) { + uri = cURI; + to = cDomain; + from = cFrom; + lang = cLang; + route = cRoute; + proxyHost = cProxyHost; + proxyPort = cProxyPort; + sslContext = cSSLContext; + compressionEnabled = cCompression; + } + + /** + * Get the URI to use to contact the connection manager. + * + * @return connection manager URI. + */ + public URI getURI() { + return uri; + } + + /** + * Get the ID of the target domain. + * + * @return domain id + */ + public String getTo() { + return to; + } + + /** + * Get the ID of the local client. + * + * @return client id, or {@code null} + */ + public String getFrom() { + return from; + } + + /** + * Get the default language of any human-readable content within the + * XML. Defaults to "en". + * + * @return XML language ID + */ + public String getLang() { + return lang; + } + + /** + * Get the routing information for messages sent to the CM. + * + * @return route attribute string, or {@code null} if no routing + * info was provided. + */ + public String getRoute() { + return route; + } + + /** + * Get the HTTP proxy host to use. + * + * @return proxy host, or {@code null} if no proxy information was specified + */ + public String getProxyHost() { + return proxyHost; + } + + /** + * Get the HTTP proxy port to use. + * + * @return proxy port, or 0 if no proxy information was specified + */ + public int getProxyPort() { + return proxyPort; + } + + /** + * Get the SSL context to use for this session. + * + * @return SSL context instance to use, or {@code null} if no + * context instance was provided. + */ + public SSLContext getSSLContext() { + return sslContext; + } + + /** + * Determines whether or not compression of the underlying data stream + * should be attempted/allowed. Defaults to {@code false}. + * + * @return {@code true} if compression should be attempted, {@code false} + * if compression is disabled or was not specified + */ + boolean isCompressionEnabled() { + return compressionEnabled; + } + +} |