Consistent comma splitting without regex overhead
Issue: SPR-14635
This commit is contained in:
		
							parent
							
								
									58fa63fdd1
								
							
						
					
					
						commit
						03609c1518
					
				| 
						 | 
				
			
			@ -274,7 +274,7 @@ public abstract class MimeTypeUtils {
 | 
			
		|||
		if (!StringUtils.hasLength(mimeTypes)) {
 | 
			
		||||
			return Collections.emptyList();
 | 
			
		||||
		}
 | 
			
		||||
		String[] tokens = mimeTypes.split(",\\s*");
 | 
			
		||||
		String[] tokens = StringUtils.tokenizeToStringArray(mimeTypes, ",");
 | 
			
		||||
		List<MimeType> result = new ArrayList<>(tokens.length);
 | 
			
		||||
		for (String token : tokens) {
 | 
			
		||||
			result.add(parseMimeType(token));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -229,10 +229,10 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
 | 
			
		|||
 | 
			
		||||
	public long[] getHeartbeat() {
 | 
			
		||||
		String rawValue = getFirstNativeHeader(STOMP_HEARTBEAT_HEADER);
 | 
			
		||||
		if (!StringUtils.hasText(rawValue)) {
 | 
			
		||||
		String[] rawValues = StringUtils.split(rawValue, ",");
 | 
			
		||||
		if (rawValues == null) {
 | 
			
		||||
			return Arrays.copyOf(DEFAULT_HEARTBEAT, 2);
 | 
			
		||||
		}
 | 
			
		||||
		String[] rawValues = StringUtils.commaDelimitedListToStringArray(rawValue);
 | 
			
		||||
		return new long[] {Long.valueOf(rawValues[0]), Long.valueOf(rawValues[1])};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +298,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	public void setHeartbeat(long cx, long cy) {
 | 
			
		||||
		setNativeHeader(STOMP_HEARTBEAT_HEADER, StringUtils.arrayToCommaDelimitedString(new Object[]{cx, cy}));
 | 
			
		||||
		setNativeHeader(STOMP_HEARTBEAT_HEADER, cx + "," + cy);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setAck(String ack) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -223,9 +223,14 @@ public class StompHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
	 * Applies to the CONNECT and CONNECTED frames.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setHeartbeat(long[] heartbeat) {
 | 
			
		||||
		Assert.notNull(heartbeat);
 | 
			
		||||
		if (heartbeat == null || heartbeat.length != 2) {
 | 
			
		||||
			throw new IllegalArgumentException("Heart-beat array must be of length 2, not " +
 | 
			
		||||
					(heartbeat != null ? heartbeat.length : "null"));
 | 
			
		||||
		}
 | 
			
		||||
		String value = heartbeat[0] + "," + heartbeat[1];
 | 
			
		||||
		Assert.isTrue(heartbeat[0] >= 0 && heartbeat[1] >= 0, "Heart-beat values cannot be negative: "  + value);
 | 
			
		||||
		if (heartbeat[0] < 0 || heartbeat[1] < 0) {
 | 
			
		||||
			throw new IllegalArgumentException("Heart-beat values cannot be negative: " + value);
 | 
			
		||||
		}
 | 
			
		||||
		set(HEARTBEAT, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -234,10 +239,10 @@ public class StompHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
	 */
 | 
			
		||||
	public long[] getHeartbeat() {
 | 
			
		||||
		String rawValue = getFirst(HEARTBEAT);
 | 
			
		||||
		if (!StringUtils.hasText(rawValue)) {
 | 
			
		||||
		String[] rawValues = StringUtils.split(rawValue, ",");
 | 
			
		||||
		if (rawValues == null) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		String[] rawValues = StringUtils.commaDelimitedListToStringArray(rawValue);
 | 
			
		||||
		return new long[] {Long.valueOf(rawValues[0]), Long.valueOf(rawValues[1])};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -497,14 +502,8 @@ public class StompHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean equals(Object other) {
 | 
			
		||||
		if (this == other) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		if (!(other instanceof StompHeaders)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		StompHeaders otherHeaders = (StompHeaders) other;
 | 
			
		||||
		return this.headers.equals(otherHeaders.headers);
 | 
			
		||||
		return (this == other || (other instanceof StompHeaders &&
 | 
			
		||||
				this.headers.equals(((StompHeaders) other).headers)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 | 
			
		|||
import org.springframework.test.web.servlet.request.RequestPostProcessor;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.util.ObjectUtils;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.util.UriComponents;
 | 
			
		||||
import org.springframework.web.util.UriComponentsBuilder;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -213,8 +214,7 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
 | 
			
		|||
	private void authType(MockHttpServletRequest request) {
 | 
			
		||||
		String authorization = header("Authorization");
 | 
			
		||||
		if (authorization != null) {
 | 
			
		||||
			String[] authzParts = authorization.split(": ");
 | 
			
		||||
			request.setAuthType(authzParts[0]);
 | 
			
		||||
			request.setAuthType(StringUtils.split(authorization, ": ")[0]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -349,9 +349,9 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
 | 
			
		|||
			request.addPreferredLocale(Locale.getDefault());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			String[] locales = locale.split(", ");
 | 
			
		||||
			for (int i = locales.length - 1; i >= 0; i--) {
 | 
			
		||||
				request.addPreferredLocale(parseLocale(locales[i]));
 | 
			
		||||
			String[] tokens = StringUtils.tokenizeToStringArray(locale, ",");
 | 
			
		||||
			for (int i = tokens.length - 1; i >= 0; i--) {
 | 
			
		||||
				request.addPreferredLocale(parseLocale(tokens[i]));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -476,7 +476,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
		List<HttpMethod> result = new ArrayList<>();
 | 
			
		||||
		String value = getFirst(ACCESS_CONTROL_ALLOW_METHODS);
 | 
			
		||||
		if (value != null) {
 | 
			
		||||
			String[] tokens = StringUtils.tokenizeToStringArray(value, ",", true, true);
 | 
			
		||||
			String[] tokens = StringUtils.tokenizeToStringArray(value, ",");
 | 
			
		||||
			for (String token : tokens) {
 | 
			
		||||
				HttpMethod resolved = HttpMethod.resolve(token);
 | 
			
		||||
				if (resolved != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -580,10 +580,10 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
	 * as specified by the {@code Accept-Charset} header.
 | 
			
		||||
	 */
 | 
			
		||||
	public List<Charset> getAcceptCharset() {
 | 
			
		||||
		List<Charset> result = new ArrayList<>();
 | 
			
		||||
		String value = getFirst(ACCEPT_CHARSET);
 | 
			
		||||
		if (value != null) {
 | 
			
		||||
			String[] tokens = value.split(",\\s*");
 | 
			
		||||
			String[] tokens = StringUtils.tokenizeToStringArray(value, ",");
 | 
			
		||||
			List<Charset> result = new ArrayList<>(tokens.length);
 | 
			
		||||
			for (String token : tokens) {
 | 
			
		||||
				int paramIdx = token.indexOf(';');
 | 
			
		||||
				String charsetName;
 | 
			
		||||
| 
						 | 
				
			
			@ -597,8 +597,11 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
					result.add(Charset.forName(charsetName));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return Collections.emptyList();
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -617,8 +620,8 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
 | 
			
		|||
	public Set<HttpMethod> getAllow() {
 | 
			
		||||
		String value = getFirst(ALLOW);
 | 
			
		||||
		if (!StringUtils.isEmpty(value)) {
 | 
			
		||||
			List<HttpMethod> result = new LinkedList<>();
 | 
			
		||||
			String[] tokens = value.split(",\\s*");
 | 
			
		||||
			String[] tokens = StringUtils.tokenizeToStringArray(value, ",");
 | 
			
		||||
			List<HttpMethod> result = new ArrayList<>(tokens.length);
 | 
			
		||||
			for (String token : tokens) {
 | 
			
		||||
				HttpMethod resolved = HttpMethod.resolve(token);
 | 
			
		||||
				if (resolved != null) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ public abstract class HttpRange {
 | 
			
		|||
		}
 | 
			
		||||
		ranges = ranges.substring(BYTE_RANGE_PREFIX.length());
 | 
			
		||||
 | 
			
		||||
		String[] tokens = ranges.split(",\\s*");
 | 
			
		||||
		String[] tokens = StringUtils.tokenizeToStringArray(ranges, ",");
 | 
			
		||||
		List<HttpRange> result = new ArrayList<>(tokens.length);
 | 
			
		||||
		for (String token : tokens) {
 | 
			
		||||
			result.add(parseRange(token));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -439,7 +439,7 @@ public class MediaType extends MimeType implements Serializable {
 | 
			
		|||
		if (!StringUtils.hasLength(mediaTypes)) {
 | 
			
		||||
			return Collections.emptyList();
 | 
			
		||||
		}
 | 
			
		||||
		String[] tokens = mediaTypes.split(",\\s*");
 | 
			
		||||
		String[] tokens = StringUtils.tokenizeToStringArray(mediaTypes, ",");
 | 
			
		||||
		List<MediaType> result = new ArrayList<>(tokens.length);
 | 
			
		||||
		for (String token : tokens) {
 | 
			
		||||
			result.add(parseMediaType(token));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -673,7 +673,7 @@ public class UriComponentsBuilder implements Cloneable {
 | 
			
		|||
	UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
 | 
			
		||||
		String forwardedHeader = headers.getFirst("Forwarded");
 | 
			
		||||
		if (StringUtils.hasText(forwardedHeader)) {
 | 
			
		||||
			String forwardedToUse = StringUtils.commaDelimitedListToStringArray(forwardedHeader)[0];
 | 
			
		||||
			String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
 | 
			
		||||
			Matcher matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
 | 
			
		||||
			if (matcher.find()) {
 | 
			
		||||
				host(matcher.group(1).trim());
 | 
			
		||||
| 
						 | 
				
			
			@ -686,10 +686,9 @@ public class UriComponentsBuilder implements Cloneable {
 | 
			
		|||
		else {
 | 
			
		||||
			String hostHeader = headers.getFirst("X-Forwarded-Host");
 | 
			
		||||
			if (StringUtils.hasText(hostHeader)) {
 | 
			
		||||
				String[] hosts = StringUtils.commaDelimitedListToStringArray(hostHeader);
 | 
			
		||||
				String hostToUse = hosts[0];
 | 
			
		||||
				if (hostToUse.contains(":")) {
 | 
			
		||||
					String[] hostAndPort = StringUtils.split(hostToUse, ":");
 | 
			
		||||
				String hostToUse = StringUtils.tokenizeToStringArray(hostHeader, ",")[0];
 | 
			
		||||
				String[] hostAndPort = StringUtils.split(hostToUse, ":");
 | 
			
		||||
				if (hostAndPort != null) {
 | 
			
		||||
					host(hostAndPort[0]);
 | 
			
		||||
					port(Integer.parseInt(hostAndPort[1]));
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -701,14 +700,12 @@ public class UriComponentsBuilder implements Cloneable {
 | 
			
		|||
 | 
			
		||||
			String portHeader = headers.getFirst("X-Forwarded-Port");
 | 
			
		||||
			if (StringUtils.hasText(portHeader)) {
 | 
			
		||||
				String[] ports = StringUtils.commaDelimitedListToStringArray(portHeader);
 | 
			
		||||
				port(Integer.parseInt(ports[0]));
 | 
			
		||||
				port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			String protocolHeader = headers.getFirst("X-Forwarded-Proto");
 | 
			
		||||
			if (StringUtils.hasText(protocolHeader)) {
 | 
			
		||||
				String[] protocols = StringUtils.commaDelimitedListToStringArray(protocolHeader);
 | 
			
		||||
				scheme(protocols[0]);
 | 
			
		||||
				scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,7 @@ import org.springframework.util.StringUtils;
 | 
			
		|||
 * e.g. extensions "foo, bar" will be executed as "bar(foo(message))".</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Brian Clozel
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 4.0
 | 
			
		||||
 * @see <a href="https://tools.ietf.org/html/rfc6455#section-9">WebSocket Protocol Extensions, RFC 6455 - Section 9</a>
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -68,46 +69,79 @@ public class WebSocketExtension {
 | 
			
		|||
	 * @param parameters the parameters
 | 
			
		||||
	 */
 | 
			
		||||
	public WebSocketExtension(String name, Map<String, String> parameters) {
 | 
			
		||||
		Assert.hasLength(name, "extension name must not be empty");
 | 
			
		||||
		Assert.hasLength(name, "Extension name must not be empty");
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		if (!CollectionUtils.isEmpty(parameters)) {
 | 
			
		||||
			Map<String, String> m = new LinkedCaseInsensitiveMap<>(parameters.size(), Locale.ENGLISH);
 | 
			
		||||
			m.putAll(parameters);
 | 
			
		||||
			this.parameters = Collections.unmodifiableMap(m);
 | 
			
		||||
			Map<String, String> map = new LinkedCaseInsensitiveMap<>(parameters.size(), Locale.ENGLISH);
 | 
			
		||||
			map.putAll(parameters);
 | 
			
		||||
			this.parameters = Collections.unmodifiableMap(map);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			this.parameters = Collections.emptyMap();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return the name of the extension
 | 
			
		||||
	 * Return the name of the extension (never {@code null) or empty}.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getName() {
 | 
			
		||||
		return this.name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return the parameters of the extension, never {@code null}
 | 
			
		||||
	 * Return the parameters of the extension (never {@code null}).
 | 
			
		||||
	 */
 | 
			
		||||
	public Map<String, String> getParameters() {
 | 
			
		||||
		return this.parameters;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean equals(Object other) {
 | 
			
		||||
		if (this == other) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		if (other == null || getClass() != other.getClass()) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		WebSocketExtension otherExt = (WebSocketExtension) other;
 | 
			
		||||
		return (this.name.equals(otherExt.name) && this.parameters.equals(otherExt.parameters));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		return this.name.hashCode() * 31 + this.parameters.hashCode();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String toString() {
 | 
			
		||||
		StringBuilder str = new StringBuilder();
 | 
			
		||||
		str.append(this.name);
 | 
			
		||||
		for (String param : parameters.keySet()) {
 | 
			
		||||
			str.append(';');
 | 
			
		||||
			str.append(param);
 | 
			
		||||
			str.append('=');
 | 
			
		||||
			str.append(this.parameters.get(param));
 | 
			
		||||
		}
 | 
			
		||||
		return str.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the given, comma-separated string into a list of {@code WebSocketExtension} objects.
 | 
			
		||||
	 * <p>This method can be used to parse a "Sec-WebSocket-Extension" extensions.
 | 
			
		||||
	 * <p>This method can be used to parse a "Sec-WebSocket-Extension" header.
 | 
			
		||||
	 * @param extensions the string to parse
 | 
			
		||||
	 * @return the list of extensions
 | 
			
		||||
	 * @throws IllegalArgumentException if the string cannot be parsed
 | 
			
		||||
	 */
 | 
			
		||||
	public static List<WebSocketExtension> parseExtensions(String extensions) {
 | 
			
		||||
		if (extensions == null || !StringUtils.hasText(extensions)) {
 | 
			
		||||
		if (!StringUtils.hasText(extensions)) {
 | 
			
		||||
			return Collections.emptyList();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			List<WebSocketExtension> result = new ArrayList<>();
 | 
			
		||||
			for (String token : extensions.split(",")) {
 | 
			
		||||
			for (String token : StringUtils.tokenizeToStringArray(extensions, ",")) {
 | 
			
		||||
				result.add(parseExtension(token));
 | 
			
		||||
			}
 | 
			
		||||
			return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +149,9 @@ public class WebSocketExtension {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private static WebSocketExtension parseExtension(String extension) {
 | 
			
		||||
		Assert.doesNotContain(extension, ",", "Expected a single extension value: " + extension);
 | 
			
		||||
		if (extension.contains(",")) {
 | 
			
		||||
			throw new IllegalArgumentException("Expected single extension value: [" + extension + "]");
 | 
			
		||||
		}
 | 
			
		||||
		String[] parts = StringUtils.tokenizeToStringArray(extension, ";");
 | 
			
		||||
		String name = parts[0].trim();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,42 +172,4 @@ public class WebSocketExtension {
 | 
			
		|||
		return new WebSocketExtension(name, parameters);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean equals(Object o) {
 | 
			
		||||
		if (this == o) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		if ((o == null) || (getClass() != o.getClass())) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		WebSocketExtension that = (WebSocketExtension) o;
 | 
			
		||||
		if (!name.equals(that.name)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		if (!parameters.equals(that.parameters)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		int result = name.hashCode();
 | 
			
		||||
		result = 31 * result + parameters.hashCode();
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String toString() {
 | 
			
		||||
		StringBuilder str = new StringBuilder();
 | 
			
		||||
		str.append(this.name);
 | 
			
		||||
		for (String param : parameters.keySet()) {
 | 
			
		||||
			str.append(';');
 | 
			
		||||
			str.append(param);
 | 
			
		||||
			str.append('=');
 | 
			
		||||
			str.append(this.parameters.get(param));
 | 
			
		||||
		}
 | 
			
		||||
		return str.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda
 | 
			
		|||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String[] getSupportedVersions() {
 | 
			
		||||
		return StringUtils.commaDelimitedListToStringArray(Version.getSupportedWireProtocolVersions());
 | 
			
		||||
		return StringUtils.tokenizeToStringArray(Version.getSupportedWireProtocolVersions(), ",");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected List<WebSocketExtension> getInstalledExtensions(WebSocketContainer container) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue