Index: test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java =================================================================== --- test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java (revision 1530689) +++ test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java (working copy) @@ -47,9 +47,9 @@ import javax.websocket.server.ServerEndpointConfig; + import org.junit.Assert; import org.junit.Test; - import org.apache.catalina.Context; import org.apache.catalina.servlets.DefaultServlet; import org.apache.catalina.startup.Tomcat; @@ -64,6 +64,7 @@ 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 @@ -141,7 +142,7 @@ MsgString msg1 = new MsgString(); msg1.setData(MESSAGE_ONE); session.getBasicRemote().sendObject(msg1); - + // Should not take very long int i = 0; while (i < 20) { @@ -172,8 +173,65 @@ i = testEvent(MsgByteEncoder.class.getName()+":destroy", i); i = testEvent(MsgByteDecoder.class.getName()+":destroy", i); } + + + + @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 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 +246,17 @@ } + @ClientEndpoint(decoders={ListStringDecoder.class}, + encoders={ListStringEncoder.class}) + public static class GenericsClient { + private Queue received = new ConcurrentLinkedQueue<>(); + + @OnMessage + public void rx(List in) { + received.add(in); + } + } + @ClientEndpoint(decoders={MsgStringDecoder.class, MsgByteDecoder.class}, encoders={MsgStringEncoder.class, MsgByteEncoder.class}) public static class Client { @@ -206,6 +275,24 @@ } + @ServerEndpoint(value=PATH_GENERICS_EP, + decoders={ListStringDecoder.class}, + encoders={ListStringEncoder.class}, + configurator=SingletonConfigurator.class) + public static class GenericsServer { + + private Queue received = new ConcurrentLinkedQueue<>(); + + + @OnMessage + public List rx(List 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}, @@ -228,7 +315,8 @@ // Echo the message back return in; } - + + public static void addLifeCycleEvent(String event){ lifeCyclesCalled.put(event, Boolean.TRUE); } @@ -412,8 +500,64 @@ return false; } } + + + public static class ListStringEncoder implements Encoder.Text> { + @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 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> { + + @Override + public void init(EndpointConfig endpointConfig) { + Server.addLifeCycleEvent(getClass().getName() + ":init"); + } + + @Override + public void destroy() { + Server.addLifeCycleEvent(getClass().getName() + ":destroy"); + } + + @Override + public List decode(String str) throws DecodeException { + List 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