blob: f82a622a6f2e9611c896b7d216c8de1d4f2a292e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 javax.websocket;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The ClientEndpointConfig is a special kind of endpoint configuration object that contains web socket configuration
* information specific only to client endpoints. Developers deploying programmatic client endpoints can create
* instances of this configuration by using a ClientEndpointConfig.Builder. Developers can override some of the
* configuration operations by providing an implementation of ClientEndpointConfig.Configurator.
*
*/
public interface ClientEndpointConfig extends EndpointConfig {
/**
* The ClientEndpointConfig.Builder is a class used for creating ClientEndpointConfig objects for the purposes of
* deploying a client endpoint. Here are some examples: Building a plain configuration with no encoders, decoders,
* subprotocols or extensions. ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build(); Building a
* configuration with no subprotocols and a custom configurator.
* <p/>
* <code>
* ClientEndpointConfig customCec = ClientEndpointConfig.Builder.create()
* .preferredSubprotocols(mySubprotocols)
* .configurator(new MyClientConfigurator())
* .build();
* </code>
*
*/
public static final class Builder {
private Configurator configurator;
private List<String> preferredSubprotocols;
private List<Extension> extensions;
private List<Class<? extends Encoder>> encoders;
private List<Class<? extends Decoder>> decoders;
private Map<String, Object> userProperties = new HashMap<String, Object>();
/**
* Creates a new builder object with no subprotocols, extensions, encoders, decoders and a null configurator.
*
* @return a new builder object
*/
public static Builder create() {
return new Builder();
}
/**
* Builds a configuration object using the attributes set on this builder.
*
* @return a new configuration object
*/
public ClientEndpointConfig build() {
if (decoders == null)
decoders = Collections.emptyList();
if (encoders == null)
encoders = Collections.emptyList();
if (extensions == null)
extensions = Collections.emptyList();
if (preferredSubprotocols == null)
preferredSubprotocols = Collections.emptyList();
return new ClientEndpointConfig() {
public List<Class<? extends Encoder>> getEncoders() {
return encoders;
}
public List<Class<? extends Decoder>> getDecoders() {
return decoders;
}
public Map<String, Object> getUserProperties() {
return userProperties;
}
public List<String> getPreferredSubprotocols() {
return preferredSubprotocols;
}
public List<Extension> getExtensions() {
return extensions;
}
public Configurator getConfigurator() {
return configurator;
}
};
}
/**
* Sets the configurator object for the configuration this builder will build.
*
* @param clientEndpointConfigurator
* the configurator
* @return the builder instance
*/
public Builder configurator(Configurator clientEndpointConfigurator) {
this.configurator = clientEndpointConfigurator;
return this;
}
/**
* Set the preferred sub protocols for the configuration this builder will build. The list is treated in order
* of preference, favorite first, that this client would like to use for its sessions.
*
* @param preferredSubprotocols
* the preferred subprotocol names.
* @return the builder instance
*/
public Builder preferredSubprotocols(List<String> preferredSubprotocols) {
this.preferredSubprotocols = preferredSubprotocols;
return this;
}
/**
* Set the extensions for the configuration this builder will build. The list is treated in order of preference,
* favorite first, that the client would like to use for its sessions.
*
* @param extensions
* the extensions
* @return the builder instance
*/
public ClientEndpointConfig.Builder extensions(List<Extension> extensions) {
this.extensions = extensions;
return this;
}
/**
* Assign the list of encoder implementation classes the client will use.
*
* @param encoders
* the encoder implementation classes
* @return the builder instance
*/
public Builder encoders(List<Class<? extends Encoder>> encoders) {
this.encoders = encoders;
return this;
}
/**
* Assign the list of decoder implementation classes the client will use.
*
* @param decoders
* the decoder implementation classes
* @return the builder instance
*/
public Builder decoders(List<Class<? extends Decoder>> decoders) {
this.decoders = decoders;
return this;
}
}
/**
* The Configurator class may be extended by developers who want to provide custom configuration algorithms, such as
* intercepting the opening handshake, or providing arbitrary methods and algorithms that can be accessed from each
* endpoint instance configured with this configurator.
*
*/
public static class Configurator {
public Configurator() {
// no-op
}
/**
* This method is called by the implementation after it has formulated the handshake request that will be used
* to initiate the connection to the server, but before it has sent any part of the request. This allows the
* developer to inspect and modify the handshake request headers prior to the start of the handshake
* interaction.
*
* @param headers
* the mutable map of handshake request headers the implementation is about to send to start the
* handshake interaction.
*/
public void beforeRequest(Map<String, List<String>> headers) {
// no-op
}
/**
* This method is called by the implementation after it has received a handshake response from the server as a
* result of a handshake interaction it initiated. The developer may implement this method in order to inspect
* the returning handshake response.
*
* @param hr
* the handshake response sent by the server.
*/
public void afterResponse(HandshakeResponse hr) {
// no-op
}
}
/**
* Return the ordered list of sub protocols a client endpoint would like to use, in order of preference, favorite
* first that this client would like to use for its sessions. This list is used to generate the
* Sec-WebSocket-Protocol header in the opening handshake for clients using this configuration. The first protocol
* name is the most preferred. See <a href="http://tools.ietf.org/html/rfc6455#section-4.1">Client Opening
* Handshake</a>.
*
* @return the list of the preferred subprotocols, the empty list if there are none
*/
List<String> getPreferredSubprotocols();
/**
* Return the extensions, in order of preference, favorite first, that this client would like to use for its
* sessions. These are the extensions that will be used to populate the Sec-WebSocket-Extensions header in the
* opening handshake for clients using this configuration. The first extension in the list is the most preferred
* extension. See <a href="http://tools.ietf.org/html/rfc6455#section-9.1">Negotiating Extensions</a>.
*
* @return the list of extensions, the empty list if there are none.
*/
List<Extension> getExtensions();
/**
* Return the custom configurator for this configuration. If the developer did not provide one, the platform default
* configurator is returned.
*
* @return the configurator in use with this configuration.
*/
ClientEndpointConfig.Configurator getConfigurator();
}