<?xml version="1.0"?>
<!--

    Copyright (c) 2013, 2017 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!DOCTYPE chapter [<!ENTITY % ents SYSTEM "tyrus.ent" > %ents;]>
<chapter xmlns="http://docbook.org/ns/docbook"
         version="5.0"
         xml:lang="en"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
                             http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
         xml:id="configurations">
    <title>Configurations</title>
    <para>
        <code>jakarta.websocket.server.ServerEndpointConfig</code> and <code>jakarta.websocket.ClientEndpointConfig</code> objects
        are used to provide the user the ability to configure websocket endpoints. Both server and client endpoints have some
        part of configuration in common, namely encoders, decoders, and user properties. The user properties may developers
        use to store the application specific data. For the developer's convenience the builders are provided for both
        ServerEndpointConfig and ClientEndpointConfig.
    </para>
    <section>
        <title><code>jakarta.websocket.server.ServerEndpointConfig</code></title>
        <para>
            The <code>jakarta.websocket.server.ServerEndpointConfig</code> is used when deploying the endpoint either via
            implementing the <code>jakarta.websocket.server.ServerApplicationConfig</code>, or via registering the programmatic endpoint
            at the <code>jakarta.websocket.server.ServerContainer</code> instance. It allows the user to create the configuration
            programmatically.
        </para>
        <para>
            The following example is used to deploy the EchoEndpoint programmatically. In the method
            <code>getEndpointClass()</code> the user has to specify the class of the deployed endpoint. In
            the example Tyrus will create an instance of <code>EchoEndpoint</code> and deploy it.
            This is the way how to tie together endpoint and it's configuration. In the method
            <code>getPath()</code> the user specifies that that the endpoint instance will be deployed at the
            path "/echo". In the method <code>public List&lt;String&gt; getSubprotocols()</code> the user
            specifies that the supported subprotocols are "echo1" and "echo2". The method <code>getExtensions()</code>
            defines the extensions the endpoint supports. Similarly the example configuration does not use any configurator.
            Method <code>public List&lt;Class&lt;? extends Encoder&gt;&gt; getEncoders()</code> defines the encoders
            used by the endpoint. The decoders and user properties map are defined in similar fashion.
        </para>
        <para>
            If the endpoint class which is about to be deployed is an annotated endpoint, note that the endpoint configuration
            will be taken from configuration object, not from the annotation on the endpoint class.
        </para>
        <example>
            <title>Configuration for EchoEndpoint Deployment</title>
<programlisting language="java" linenumbering="numbered">public class EchoEndpointConfig implements ServerEndpointConfig{

    private final Map&lt;String, Object&gt; userProperties = new HashMap&lt;String, Object&gt;();

    @Override
    public Class&lt;?&gt; getEndpointClass() {
        return EchoEndpoint.class;
    }

    @Override
    public String getPath() {
        return "/echo";
    }

    @Override
    public List&lt;String&gt; getSubprotocols() {
        return Arrays.asList("echo1","echo2");
    }

    @Override
    public List&lt;Extension&gt; getExtensions() {
        return null;
    }

    @Override
    public Configurator getConfigurator() {
        return null;
    }

    @Override
    public List&lt;Class&lt;? extends Encoder&gt;&gt; getEncoders() {
        return Arrays.asList(SampleEncoder.class);
    }

    @Override
    public List&lt;Class&lt;? extends Decoder&gt;&gt; getDecoders() {
        return Arrays.asList(SampleDecoder.class);
    }

    @Override
    public Map&lt;String, Object&gt; getUserProperties() {
        return userProperties;
    }
}</programlisting>
        </example>
        <para>
            To make the development easy the <emphasis>jakarta.websocket.server.ServerEndpointConfig</emphasis> provides a builder to construct
            the configuration object:
            <example>
                <title>ServerEndpointConfigu built using Builder</title>
<programlisting language="java" linenumbering="numbered">ServerEndpointConfig config = ServerEndpointConfig.Builder.create(EchoEndpoint.class,"/echo").
    decoders(Arrays.&lt;Class&lt;? extends Decoder&gt;&gt;asList(JsonDecoder.class)).
    encoders(Arrays.&lt;Class&lt; extends Encoder&gt;&gt;asList(JsonEncoder.class)).build();</programlisting>
            </example>
        </para>
    </section>
    <section>
        <title><code>jakarta.websocket.ClientEndpointConfig</code></title>
        <para>
            The <code>jakarta.websocket.ClientEndpointConfig</code> is used when deploying the programmatic client endpoint
            via registering the programmatic endpoint at the <code>WebSocketContainer</code> instance. Some of
            the configuration methods come from the <code>EndpointConfig</code>class, which is extended by both
            <code>jakarta.websocket.server.ServerEndpointConfig</code> and <code>jakarta.websocket.ClientEndpointConfig</code>. Then there are methods
            for configuring the preferred subprotocols the client endpoint wants to use and supported extensions. It is
            also possible to use the ClientEndpointConfig.Configurator in order to be able to affect the endpoint behaviour
            before and after request.
        </para>
        <para>
            Similarly to the ServerEndpointConfig, there is a Builder provided to construct the configuration easily:
        </para>
        <example>
            <title>ClientEndpointConfig built using Builder</title>
<programlisting language="java" linenumbering="numbered">ClientEndpointConfig.Builder.create().
    decoders(Arrays.&lt;Class&lt;? extends Decoder&gt;&gt;asList(JsonDecoder.class)).
    encoders(Arrays.&lt;Class&lt;? extends Encoder&gt;&gt;asList(JsonEncoder.class)).
    preferredSubprotocols(Arrays.asList("echo1", "echo2")).build();</programlisting>
        </example>
    </section>
</chapter>
