Author: markt
Date: Wed Jun 26 12:36:58 2013
New Revision: 1496905

URL: http://svn.apache.org/r1496905
Log:
More work for BZ 55143
Add support for byte[], InopuStream and Reader message handlers

Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
    
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeBinary.java
    
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeText.java
    tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
    tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java
    tomcat/trunk/test/org/apache/tomcat/websocket/TesterEchoServer.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=1496905&r1=1496904&r2=1496905&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Wed Jun 26 12:36:58 
2013
@@ -16,6 +16,8 @@
  */
 package org.apache.tomcat.websocket;
 
+import java.io.InputStream;
+import java.io.Reader;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -334,9 +336,33 @@ public class Util {
                     new MessageHandlerResult(listener,
                             MessageHandlerResultType.PONG);
             results.add(result);
-            // TODO byte[], Reader, InputStream
+        // Relatively simple cases - handler needs wrapping but no decoder to
+        // convert it to one of the types expected by the frame handling code
+        } else if (byte[].class.isAssignableFrom(target)) {
+            MessageHandlerResult result = new MessageHandlerResult(
+                    new PojoMessageHandlerWholeBinary(listener,
+                            getOnMessageMethod(listener), null,
+                            endpointConfig, null, new Object[1], 0, true, -1,
+                            false),
+                    MessageHandlerResultType.BINARY);
+            results.add(result);
+        } else if (InputStream.class.isAssignableFrom(target)) {
+            MessageHandlerResult result = new MessageHandlerResult(
+                    new PojoMessageHandlerWholeBinary(listener,
+                            getOnMessageMethod(listener), null,
+                            endpointConfig, null, new Object[1], 0, true, -1,
+                            true),
+                    MessageHandlerResultType.BINARY);
+            results.add(result);
+        } else if (Reader.class.isAssignableFrom(target)) {
+            MessageHandlerResult result = new MessageHandlerResult(
+                    new PojoMessageHandlerWholeText(listener,
+                            getOnMessageMethod(listener), null,
+                            endpointConfig, null, new Object[1], 0, true, -1),
+                    MessageHandlerResultType.BINARY);
+            results.add(result);
         } else {
-            // More complex case - listener that requires a decoder
+        // More complex case - listener that requires a decoder
             DecoderMatch decoderMatch;
             try {
                 decoderMatch = new DecoderMatch(target,
@@ -347,16 +373,19 @@ public class Util {
             Method m = getOnMessageMethod(listener);
             if (decoderMatch.getBinaryDecoders().size() > 0) {
                 MessageHandlerResult result = new MessageHandlerResult(
-                        new PojoMessageHandlerWholeBinary(listener, m,
+                        new PojoMessageHandlerWholeBinary(listener, m, null,
                                 endpointConfig,
-                                decoderMatch.getBinaryDecoders()),
+                                decoderMatch.getBinaryDecoders(), new 
Object[1],
+                                0, false, -1, false),
                         MessageHandlerResultType.BINARY);
                 results.add(result);
             }
             if (decoderMatch.getTextDecoders().size() > 0) {
                 MessageHandlerResult result = new MessageHandlerResult(
-                        new PojoMessageHandlerWholeText(listener, m,
-                                endpointConfig, 
decoderMatch.getTextDecoders()),
+                        new PojoMessageHandlerWholeText(listener, m, null,
+                                endpointConfig,
+                                decoderMatch.getTextDecoders(), new Object[1],
+                                0, false, -1),
                         MessageHandlerResultType.TEXT);
                 results.add(result);
             }

Modified: 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeBinary.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeBinary.java?rev=1496905&r1=1496904&r2=1496905&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeBinary.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeBinary.java
 Wed Jun 26 12:36:58 2013
@@ -28,7 +28,6 @@ import javax.websocket.Decoder;
 import javax.websocket.Decoder.Binary;
 import javax.websocket.Decoder.BinaryStream;
 import javax.websocket.EndpointConfig;
-import javax.websocket.MessageHandler;
 import javax.websocket.Session;
 
 import org.apache.tomcat.util.res.StringManager;
@@ -47,24 +46,29 @@ public class PojoMessageHandlerWholeBina
     private final boolean isForInputStream;
 
     public PojoMessageHandlerWholeBinary(Object pojo, Method method,
-            Session session, EndpointConfig config, Object[] params,
+            Session session, EndpointConfig config,
+            List<Class<? extends Decoder>> decoderClazzes, Object[] params,
             int indexPayload, boolean convert, int indexSession,
             boolean isForInputStream) {
         super(pojo, method, session, params, indexPayload, convert,
                 indexSession);
         try {
-            for (Class<? extends Decoder> decoderClazz : config.getDecoders()) 
{
-                if (Binary.class.isAssignableFrom(decoderClazz)) {
-                    Binary<?> decoder = (Binary<?>) decoderClazz.newInstance();
-                    decoder.init(config);
-                    decoders.add(decoder);
-                } else if (BinaryStream.class.isAssignableFrom(decoderClazz)) {
-                    BinaryStream<?> decoder =
-                            (BinaryStream<?>) decoderClazz.newInstance();
-                    decoder.init(config);
-                    decoders.add(decoder);
-                } else {
-                    // Text decoder - ignore it
+            if (decoderClazzes != null) {
+                for (Class<? extends Decoder> decoderClazz : decoderClazzes) {
+                    if (Binary.class.isAssignableFrom(decoderClazz)) {
+                        Binary<?> decoder =
+                                (Binary<?>) decoderClazz.newInstance();
+                        decoder.init(config);
+                        decoders.add(decoder);
+                    } else if (BinaryStream.class.isAssignableFrom(
+                            decoderClazz)) {
+                        BinaryStream<?> decoder =
+                                (BinaryStream<?>) decoderClazz.newInstance();
+                        decoder.init(config);
+                        decoders.add(decoder);
+                    } else {
+                        // Text decoder - ignore it
+                    }
                 }
             }
         } catch (IllegalAccessException | InstantiationException e) {
@@ -74,25 +78,6 @@ public class PojoMessageHandlerWholeBina
     }
 
 
-    public PojoMessageHandlerWholeBinary(MessageHandler listener,
-            Method method, EndpointConfig config,
-            List<Class<? extends Decoder>> binaryDecoders) {
-        super(listener, method, null, new Object[1], -1, false, -1);
-
-        try {
-            for (Class<? extends Decoder> decoderClazz : binaryDecoders) {
-                Binary<?> decoder = (Binary<?>) decoderClazz.newInstance();
-                decoder.init(config);
-                decoders.add(decoder);
-            }
-        } catch (IllegalAccessException | InstantiationException e) {
-            throw new IllegalArgumentException(e);
-        }
-
-        this.isForInputStream = false;
-    }
-
-
     @Override
     protected Object decode(ByteBuffer message) throws DecodeException {
         for (Decoder decoder : decoders) {

Modified: 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeText.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeText.java?rev=1496905&r1=1496904&r2=1496905&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeText.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMessageHandlerWholeText.java
 Wed Jun 26 12:36:58 2013
@@ -27,7 +27,6 @@ import javax.websocket.Decoder;
 import javax.websocket.Decoder.Text;
 import javax.websocket.Decoder.TextStream;
 import javax.websocket.EndpointConfig;
-import javax.websocket.MessageHandler;
 import javax.websocket.Session;
 
 import org.apache.tomcat.util.res.StringManager;
@@ -47,7 +46,8 @@ public class PojoMessageHandlerWholeText
     private final Class<?> primitiveType;
 
     public PojoMessageHandlerWholeText(Object pojo, Method method,
-            Session session, EndpointConfig config, Object[] params,
+            Session session, EndpointConfig config,
+            List<Class<? extends Decoder>> decoderClazzes, Object[] params,
             int indexPayload, boolean convert, int indexSession) {
         super(pojo, method, session, params, indexPayload, convert,
                 indexSession);
@@ -62,7 +62,7 @@ public class PojoMessageHandlerWholeText
         }
 
         try {
-            for (Class<? extends Decoder> decoderClazz : config.getDecoders()) 
{
+            for (Class<? extends Decoder> decoderClazz : decoderClazzes) {
                 if (Text.class.isAssignableFrom(decoderClazz)) {
                     Text<?> decoder = (Text<?>) decoderClazz.newInstance();
                     decoder.init(config);
@@ -82,25 +82,6 @@ public class PojoMessageHandlerWholeText
     }
 
 
-    public PojoMessageHandlerWholeText(MessageHandler listener,
-            Method method, EndpointConfig config,
-            List<Class<? extends Decoder>> textDecoders) {
-        super(listener, method, null, new Object[1], -1, false, -1);
-
-        try {
-            for (Class<? extends Decoder> decoderClazz : textDecoders) {
-                Text<?> decoder = (Text<?>) decoderClazz.newInstance();
-                decoder.init(config);
-                decoders.add(decoder);
-            }
-        } catch (IllegalAccessException | InstantiationException e) {
-            throw new IllegalArgumentException(e);
-        }
-
-        primitiveType = null;
-    }
-
-
     @Override
     protected Object decode(String message) throws DecodeException {
         // Handle primitives

Modified: 
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java?rev=1496905&r1=1496904&r2=1496905&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java 
Wed Jun 26 12:36:58 2013
@@ -522,26 +522,28 @@ public class PojoMethodMapping {
                 // Basic
                 if (indexString != -1) {
                     mh = new PojoMessageHandlerWholeText(pojo, m,  session,
-                            config, params, indexString, false, indexSession);
+                            config, config.getDecoders(), params, indexString,
+                            false, indexSession);
                 } else if (indexPrimitive != -1) {
                     mh = new PojoMessageHandlerWholeText(pojo, m, session,
-                            config, params, indexPrimitive, false,
-                            indexSession);
+                            config, config.getDecoders(), params,
+                            indexPrimitive, false, indexSession);
                 } else if (indexByteArray != -1) {
                     mh = new PojoMessageHandlerWholeBinary(pojo, m, session,
-                            config, params, indexByteArray, true, indexSession,
-                            false);
+                            config, config.getDecoders(), params,
+                            indexByteArray, true, indexSession, false);
                 } else if (indexByteBuffer != -1) {
                     mh = new PojoMessageHandlerWholeBinary(pojo, m, session,
-                            config, params, indexByteBuffer, false,
-                            indexSession, false);
+                            config, config.getDecoders(), params,
+                            indexByteBuffer, false, indexSession, false);
                 } else if (indexInputStream != -1) {
                     mh = new PojoMessageHandlerWholeBinary(pojo, m, session,
-                            config, params, indexInputStream, true, 
indexSession,
-                            true);
+                            config, config.getDecoders(), params,
+                            indexInputStream, true, indexSession, true);
                 } else if (indexReader != -1) {
                     mh = new PojoMessageHandlerWholeText(pojo, m, session,
-                            config, params, indexReader, true, indexSession);
+                            config, config.getDecoders(), params, indexReader,
+                            true, indexSession);
                 } else {
                     mh = new PojoMessageHandlerWholePong(pojo, m, session,
                             params, indexPong, false, indexSession);

Modified: 
tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java?rev=1496905&r1=1496904&r2=1496905&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java 
(original)
+++ tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java 
Wed Jun 26 12:36:58 2013
@@ -798,4 +798,54 @@ public class TestWsWebSocketContainer ex
         Assert.assertEquals(1, messages.size());
         Assert.assertEquals(MESSAGE_STRING_1, messages.get(0));
     }
+
+
+    @Test
+    public void testMaxMessageSize01() throws Exception {
+        doMaxMessageSize(TesterEchoServer.BasicLimit.MAX_SIZE - 1, true);
+    }
+
+
+    @Test
+    public void testMaxMessageSize02() throws Exception {
+        doMaxMessageSize(TesterEchoServer.BasicLimit.MAX_SIZE, true);
+    }
+
+
+    @Test
+    public void testMaxMessageSize03() throws Exception {
+        doMaxMessageSize(TesterEchoServer.BasicLimit.MAX_SIZE + 1, false);
+    }
+
+
+    private void doMaxMessageSize(long size, boolean expectOpen)
+            throws Exception {
+
+        Tomcat tomcat = getTomcatInstance();
+        // Must have a real docBase - just use temp
+        Context ctx =
+            tomcat.addContext("", System.getProperty("java.io.tmpdir"));
+        ctx.addApplicationListener(new ApplicationListener(
+                TesterEchoServer.Config.class.getName(), false));
+        Tomcat.addServlet(ctx, "default", new DefaultServlet());
+        ctx.addServletMapping("/", "default");
+
+        tomcat.start();
+
+        WebSocketContainer wsContainer =
+                ContainerProvider.getWebSocketContainer();
+
+        Session s = connectToEchoServerBasic(wsContainer, EndpointA.class);
+
+        // 9 bytes
+        StringBuilder msg = new StringBuilder();
+        for (long i = 0; i < size; i++) {
+            msg.append('x');
+        }
+
+        s.getBasicRemote().sendText(msg.toString());
+
+        Assert.assertEquals(Boolean.valueOf(expectOpen),
+                Boolean.valueOf(s.isOpen()));
+    }
 }

Modified: tomcat/trunk/test/org/apache/tomcat/websocket/TesterEchoServer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TesterEchoServer.java?rev=1496905&r1=1496904&r2=1496905&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/websocket/TesterEchoServer.java 
(original)
+++ tomcat/trunk/test/org/apache/tomcat/websocket/TesterEchoServer.java Wed Jun 
26 12:36:58 2013
@@ -35,6 +35,7 @@ public class TesterEchoServer {
 
         public static final String PATH_ASYNC = "/echoAsync";
         public static final String PATH_BASIC = "/echoBasic";
+        public static final String PATH_BASIC_LIMIT = "/echoBasicLimit";
 
         @Override
         public void contextInitialized(ServletContextEvent sce) {
@@ -45,6 +46,7 @@ public class TesterEchoServer {
             try {
                 sc.addEndpoint(Async.class);
                 sc.addEndpoint(Basic.class);
+                sc.addEndpoint(BasicLimit.class);
             } catch (DeploymentException e) {
                 throw new IllegalStateException(e);
             }
@@ -113,4 +115,38 @@ public class TesterEchoServer {
             }
         }
     }
+
+
+    @ServerEndpoint("/echoBasicLimit")
+    public static class BasicLimit {
+
+        public static final long MAX_SIZE = 10;
+
+        @OnMessage(maxMessageSize = MAX_SIZE)
+        public void echoTextMessage(Session session, String msg) {
+            try {
+                session.getBasicRemote().sendText(msg);
+            } catch (IOException e) {
+                try {
+                    session.close();
+                } catch (IOException e1) {
+                    // Ignore
+                }
+            }
+        }
+
+
+        @OnMessage(maxMessageSize = MAX_SIZE)
+        public void echoBinaryMessage(Session session, ByteBuffer msg) {
+            try {
+                session.getBasicRemote().sendBinary(msg);
+            } catch (IOException e) {
+                try {
+                    session.close();
+                } catch (IOException e1) {
+                    // Ignore
+                }
+            }
+        }
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to