Author: markt Date: Fri Oct 18 07:40:00 2013 New Revision: 1533347 URL: http://svn.apache.org/r1533347 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55664 Correctly handle Encoder, Decoder and MessageHandler implementations that use a generic type such as Encoder.Text<List<String>>
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Util.java tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Util.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/Util.java?rev=1533347&r1=1533346&r2=1533347&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Fri Oct 18 07:40:00 2013 @@ -164,8 +164,8 @@ public class Util { } - public static Class<?> getDecoderType(Class<? extends Decoder> Decoder) { - return (Class<?>) Util.getGenericType(Decoder.class, Decoder); + public static Class<?> getDecoderType(Class<? extends Decoder> decoder) { + return (Class<?>) Util.getGenericType(Decoder.class, decoder); } @@ -229,6 +229,8 @@ public class Util { private static Object getTypeParameter(Class<?> clazz, Type argType) { if (argType instanceof Class<?>) { return argType; + } else if (argType instanceof ParameterizedType) { + return ((ParameterizedType) argType).getRawType(); } else { TypeVariable<?>[] tvs = clazz.getTypeParameters(); for (int i = 0; i < tvs.length; i++) { Modified: tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java?rev=1533347&r1=1533346&r2=1533347&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java (original) +++ tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java Fri Oct 18 07:40:00 2013 @@ -16,6 +16,8 @@ */ package org.apache.tomcat.websocket; +import java.util.List; + import javax.websocket.EncodeException; import javax.websocket.Encoder; import javax.websocket.EndpointConfig; @@ -101,6 +103,13 @@ public class TestUtil { } + @Test + public void testGetEncoderTypeSimpleWithGenericType() { + Assert.assertEquals(List.class, + Util.getEncoderType(SimpleEncoderWithGenericType.class)); + } + + private static class SimpleMessageHandler implements MessageHandler.Whole<String> { @Override @@ -281,4 +290,24 @@ public class TestUtil { // NO-OP } } + + + private static class SimpleEncoderWithGenericType + implements Encoder.Text<List<String>> { + + @Override + public void init(EndpointConfig endpointConfig) { + // NO-OP + } + + @Override + public void destroy() { + // NO-OP + } + + @Override + public String encode(List<String> object) throws EncodeException { + return null; + } + } } Modified: tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java?rev=1533347&r1=1533346&r2=1533347&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java (original) +++ tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java Fri Oct 18 07:40:00 2013 @@ -46,7 +46,6 @@ import javax.websocket.server.ServerCont import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; - import org.junit.Assert; import org.junit.Test; @@ -64,6 +63,7 @@ public class TestEncodingDecoding extend private static final String MESSAGE_ONE = "message-one"; private static final String PATH_PROGRAMMATIC_EP = "/echoProgrammaticEP"; private static final String PATH_ANNOTATED_EP = "/echoAnnotatedEP"; + private static final String PATH_GENERICS_EP = "/echoGenericsEP"; @Test @@ -174,6 +174,56 @@ public class TestEncodingDecoding extend } + @Test + public void testGenericsCoders() throws Exception { + // Set up utility classes + GenericsServer server = new GenericsServer(); + SingletonConfigurator.setInstance(server); + ServerConfigListener.setPojoClazz(GenericsServer.class); + + Tomcat tomcat = getTomcatInstance(); + // Must have a real docBase - just use temp + Context ctx = + tomcat.addContext("", System.getProperty("java.io.tmpdir")); + ctx.addApplicationListener(new ApplicationListener( + ServerConfigListener.class.getName(), false)); + Tomcat.addServlet(ctx, "default", new DefaultServlet()); + ctx.addServletMapping("/", "default"); + + WebSocketContainer wsContainer = + ContainerProvider.getWebSocketContainer(); + + tomcat.start(); + + GenericsClient client = new GenericsClient(); + URI uri = new URI("ws://localhost:" + getPort() + PATH_GENERICS_EP); + Session session = wsContainer.connectToServer(client, uri); + + ArrayList<String> list = new ArrayList<>(2); + list.add("str1"); + list.add("str2"); + session.getBasicRemote().sendObject(list); + + // Should not take very long + int i = 0; + while (i < 20) { + if (server.received.size() > 0 && client.received.size() > 0) { + break; + } + Thread.sleep(100); + } + + // Check messages were received + Assert.assertEquals(1, server.received.size()); + Assert.assertEquals(server.received.peek().toString(), "[str1, str2]"); + + Assert.assertEquals(1, client.received.size()); + Assert.assertEquals(client.received.peek().toString(), "[str1, str2]"); + + session.close(); + } + + private int testEvent(String name, int count) throws InterruptedException { int i = count; while (i < 50) { @@ -188,6 +238,18 @@ public class TestEncodingDecoding extend } + @ClientEndpoint(decoders={ListStringDecoder.class}, + encoders={ListStringEncoder.class}) + public static class GenericsClient { + private Queue<Object> received = new ConcurrentLinkedQueue<>(); + + @OnMessage + public void rx(List<String> in) { + received.add(in); + } + } + + @ClientEndpoint(decoders={MsgStringDecoder.class, MsgByteDecoder.class}, encoders={MsgStringEncoder.class, MsgByteEncoder.class}) public static class Client { @@ -206,6 +268,24 @@ public class TestEncodingDecoding extend } + @ServerEndpoint(value=PATH_GENERICS_EP, + decoders={ListStringDecoder.class}, + encoders={ListStringEncoder.class}, + configurator=SingletonConfigurator.class) + public static class GenericsServer { + + private Queue<Object> received = new ConcurrentLinkedQueue<>(); + + + @OnMessage + public List<String> rx(List<String> in) { + received.add(in); + // Echo the message back + return in; + } + } + + @ServerEndpoint(value=PATH_ANNOTATED_EP, decoders={MsgStringDecoder.class, MsgByteDecoder.class}, encoders={MsgStringEncoder.class, MsgByteEncoder.class}, @@ -414,6 +494,61 @@ public class TestEncodingDecoding extend } + public static class ListStringEncoder implements Encoder.Text<List<String>> { + + @Override + public void init(EndpointConfig endpointConfig) { + Server.addLifeCycleEvent(getClass().getName() + ":init"); + } + + @Override + public void destroy() { + Server.addLifeCycleEvent(getClass().getName() + ":destroy"); + } + + @Override + public String encode(List<String> str) throws EncodeException { + StringBuffer sbuf = new StringBuffer(); + sbuf.append("["); + for (String s: str){ + sbuf.append(s).append(","); + } + sbuf.deleteCharAt(sbuf.lastIndexOf(",")).append("]"); + return sbuf.toString(); + } + } + + + public static class ListStringDecoder implements Decoder.Text<List<String>> { + + @Override + public void init(EndpointConfig endpointConfig) { + Server.addLifeCycleEvent(getClass().getName() + ":init"); + } + + @Override + public void destroy() { + Server.addLifeCycleEvent(getClass().getName() + ":destroy"); + } + + @Override + public List<String> decode(String str) throws DecodeException { + List<String> lst = new ArrayList<>(1); + str = str.substring(1,str.length()-1); + String[] strings = str.split(","); + for (String t : strings){ + lst.add(t); + } + return lst; + } + + @Override + public boolean willDecode(String str) { + return str.startsWith("[") && str.endsWith("]"); + } + } + + public static class ProgramaticServerEndpointConfig extends WsContextListener { @Override --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org