All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.neovisionaries.ws.client.WebSocketExtension Maven / Gradle / Ivy

There is a newer version: 2.14
Show newest version
/*
 * Copyright (C) 2015-2016 Neo Visionaries Inc.
 *
 * 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.neovisionaries.ws.client;


import java.util.LinkedHashMap;
import java.util.Map;


/**
 * A class to hold the name and the parameters of
 * a WebSocket extension.
 */
public class WebSocketExtension
{
    /**
     * The name of permessage-deflate extension that is
     * defined in 7. The "permessage-deflate" Extension in RFC 7692.
     *
     * @since 1.17
     */
    public static final String PERMESSAGE_DEFLATE = "permessage-deflate";


    private final String mName;
    private final Map mParameters;


    /**
     * Constructor with an extension name.
     *
     * @param name
     *         The extension name.
     *
     * @throws IllegalArgumentException
     *         The given name is not a valid token.
     */
    public WebSocketExtension(String name)
    {
        // Check the validity of the name.
        if (Token.isValid(name) == false)
        {
            // The name is not a valid token.
            throw new IllegalArgumentException("'name' is not a valid token.");
        }

        mName       = name;
        mParameters = new LinkedHashMap();
    }


    /**
     * Copy constructor.
     *
     * @param source
     *         A source extension. Must not be {@code null}.
     *
     * @throws IllegalArgumentException
     *         The given argument is {@code null}.
     *
     * @since 1.6
     */
    public WebSocketExtension(WebSocketExtension source)
    {
        if (source == null)
        {
            // If the given instance is null.
            throw new IllegalArgumentException("'source' is null.");
        }

        mName       = source.getName();
        mParameters = new LinkedHashMap(source.getParameters());
    }


    /**
     * Get the extension name.
     *
     * @return
     *         The extension name.
     */
    public String getName()
    {
        return mName;
    }


    /**
     * Get the parameters.
     *
     * @return
     *         The parameters.
     */
    public Map getParameters()
    {
        return mParameters;
    }


    /**
     * Check if the parameter identified by the key is contained.
     *
     * @param key
     *         The name of the parameter.
     *
     * @return
     *         {@code true} if the parameter is contained.
     */
    public boolean containsParameter(String key)
    {
        return mParameters.containsKey(key);
    }


    /**
     * Get the value of the specified parameter.
     *
     * @param key
     *         The name of the parameter.
     *
     * @return
     *         The value of the parameter. {@code null} may be returned.
     */
    public String getParameter(String key)
    {
        return mParameters.get(key);
    }


    /**
     * Set a value to the specified parameter.
     *
     * @param key
     *         The name of the parameter.
     *
     * @param value
     *         The value of the parameter. If not {@code null}, it must be
     *         a valid token. Note that RFC 6455 says "When using the quoted-string syntax
     *         variant, the value after quoted-string unescaping MUST
     *         conform to the 'token' ABNF."
     *
     * @return
     *         {@code this} object.
     *
     * @throws IllegalArgumentException
     *         
    *
  • The key is not a valid token. *
  • The value is not {@code null} and it is not a valid token. *
*/ public WebSocketExtension setParameter(String key, String value) { // Check the validity of the key. if (Token.isValid(key) == false) { // The key is not a valid token. throw new IllegalArgumentException("'key' is not a valid token."); } // If the value is not null. if (value != null) { // Check the validity of the value. if (Token.isValid(value) == false) { // The value is not a valid token. throw new IllegalArgumentException("'value' is not a valid token."); } } mParameters.put(key, value); return this; } /** * Stringify this object into the format "{name}[; {key}[={value}]]*". */ @Override public String toString() { StringBuilder builder = new StringBuilder(mName); for (Map.Entry entry : mParameters.entrySet()) { // "; {key}" builder.append("; ").append(entry.getKey()); String value = entry.getValue(); if (value != null && value.length() != 0) { // "={value}" builder.append("=").append(value); } } return builder.toString(); } /** * Validate this instance. This method is expected to be overridden. */ void validate() throws WebSocketException { } /** * Parse a string as a {@link WebSocketExtension}. The input string * should comply with the format described in 9.1. Negotiating * Extensions in RFC 6455. * * @param string * A string that represents a WebSocket extension. * * @return * A new {@link WebSocketExtension} instance that represents * the given string. If the input string does not comply with * RFC 6455, {@code null} is returned. */ public static WebSocketExtension parse(String string) { if (string == null) { return null; } // Split the string by semi-colons. String[] elements = string.trim().split("\\s*;\\s*"); if (elements.length == 0) { // Even an extension name is not included. return null; } // The first element is the extension name. String name = elements[0]; if (Token.isValid(name) == false) { // The extension name is not a valid token. return null; } // Create an instance for the extension name. WebSocketExtension extension = createInstance(name); // For each "{key}[={value}]". for (int i = 1; i < elements.length; ++i) { // Split by '=' to get the key and the value. String[] pair = elements[i].split("\\s*=\\s*", 2); // If {key} is not contained. if (pair.length == 0 || pair[0].length() == 0) { // Ignore. continue; } // The name of the parameter. String key = pair[0]; if (Token.isValid(key) == false) { // The parameter name is not a valid token. // Ignore this parameter. continue; } // The value of the parameter. String value = extractValue(pair); if (value != null) { if (Token.isValid(value) == false) { // The parameter value is not a valid token. // Ignore this parameter. continue; } } // Add the pair of the key and the value. extension.setParameter(key, value); } return extension; } private static String extractValue(String[] pair) { if (pair.length != 2) { return null; } return Token.unquote(pair[1]); } private static WebSocketExtension createInstance(String name) { if (PERMESSAGE_DEFLATE.equals(name)) { return new PerMessageDeflateExtension(name); } return new WebSocketExtension(name); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy