Author: remm
Date: Fri Nov 28 10:33:35 2014
New Revision: 1642282

URL: http://svn.apache.org/r1642282
Log:
Fix apparent edge cases with handlers (partial ones for byte[]), decoders 
(should be passed on to handlers) and encoders (byte[] does not need a 
mandatory encoder).

Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
    tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.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=1642282&r1=1642281&r2=1642282&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Fri Nov 28 10:33:35 
2014
@@ -49,6 +49,7 @@ import javax.websocket.PongMessage;
 import javax.websocket.Session;
 
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.websocket.pojo.PojoMessageHandlerPartialBinary;
 import org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBinary;
 import org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeText;
 
@@ -381,61 +382,67 @@ public class Util {
             results.add(result);
         // 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), session,
-                            endpointConfig, null, new Object[1], 0, true, -1,
-                            false, -1),
-                    MessageHandlerResultType.BINARY);
-            results.add(result);
-        } else if (InputStream.class.isAssignableFrom(target)) {
-            MessageHandlerResult result = new MessageHandlerResult(
-                    new PojoMessageHandlerWholeBinary(listener,
-                            getOnMessageMethod(listener), session,
-                            endpointConfig, null, new Object[1], 0, true, -1,
-                            true, -1),
-                    MessageHandlerResultType.BINARY);
-            results.add(result);
-        } else if (Reader.class.isAssignableFrom(target)) {
-            MessageHandlerResult result = new MessageHandlerResult(
-                    new PojoMessageHandlerWholeText(listener,
-                            getOnMessageMethod(listener), session,
-                            endpointConfig, null, new Object[1], 0, true, -1,
-                            -1),
-                    MessageHandlerResultType.TEXT);
-            results.add(result);
         } else {
-        // More complex case - listener that requires a decoder
-            DecoderMatch decoderMatch;
-            try {
-                List<Class<? extends Decoder>> decoders =
-                        endpointConfig.getDecoders();
-                @SuppressWarnings("unchecked")
-                List<DecoderEntry> decoderEntries = getDecoders(
-                        decoders.toArray(new Class[decoders.size()]));
-                decoderMatch = new DecoderMatch(target, decoderEntries);
-            } catch (DeploymentException e) {
-                throw new IllegalArgumentException(e);
-            }
-            Method m = getOnMessageMethod(listener);
-            if (decoderMatch.getBinaryDecoders().size() > 0) {
+            if (byte[].class.isAssignableFrom(target)) {
+                boolean whole = 
MessageHandler.Whole.class.isAssignableFrom(listener.getClass());
                 MessageHandlerResult result = new MessageHandlerResult(
-                        new PojoMessageHandlerWholeBinary(listener, m, session,
-                                endpointConfig,
-                                decoderMatch.getBinaryDecoders(), new 
Object[1],
-                                0, false, -1, false, -1),
+                        whole ? new PojoMessageHandlerWholeBinary(listener,
+                                        getOnMessageMethod(listener), session,
+                                        endpointConfig, matchDecoders(target, 
endpointConfig, true),
+                                        new Object[1], 0, true, -1, false, -1) 
:
+                                new PojoMessageHandlerPartialBinary(listener,
+                                        getOnMessagePartialMethod(listener), 
session,
+                                        new Object[2], 0, true, 1, -1, -1),
                         MessageHandlerResultType.BINARY);
                 results.add(result);
-            }
-            if (decoderMatch.getTextDecoders().size() > 0) {
+            } else if (InputStream.class.isAssignableFrom(target)) {
+                MessageHandlerResult result = new MessageHandlerResult(
+                        new PojoMessageHandlerWholeBinary(listener,
+                                getOnMessageMethod(listener), session,
+                                endpointConfig, matchDecoders(target, 
endpointConfig, true),
+                                new Object[1], 0, true, -1, true, -1),
+                        MessageHandlerResultType.BINARY);
+                results.add(result);
+            } else if (Reader.class.isAssignableFrom(target)) {
                 MessageHandlerResult result = new MessageHandlerResult(
-                        new PojoMessageHandlerWholeText(listener, m, session,
-                                endpointConfig,
-                                decoderMatch.getTextDecoders(), new Object[1],
-                                0, false, -1, -1),
+                        new PojoMessageHandlerWholeText(listener,
+                                getOnMessageMethod(listener), session,
+                                endpointConfig, matchDecoders(target, 
endpointConfig, false),
+                                new Object[1], 0, true, -1, -1),
                         MessageHandlerResultType.TEXT);
                 results.add(result);
+            } else {
+                // More complex case - listener that requires a decoder
+                DecoderMatch decoderMatch;
+                try {
+                    List<Class<? extends Decoder>> decoders =
+                            endpointConfig.getDecoders();
+                    @SuppressWarnings("unchecked")
+                    List<DecoderEntry> decoderEntries = getDecoders(
+                            decoders.toArray(new Class[decoders.size()]));
+                    decoderMatch = new DecoderMatch(target, decoderEntries);
+                } catch (DeploymentException e) {
+                    throw new IllegalArgumentException(e);
+                }
+                Method m = getOnMessageMethod(listener);
+                if (decoderMatch.getBinaryDecoders().size() > 0) {
+                    MessageHandlerResult result = new MessageHandlerResult(
+                            new PojoMessageHandlerWholeBinary(listener, m, 
session,
+                                    endpointConfig,
+                                    decoderMatch.getBinaryDecoders(), new 
Object[1],
+                                    0, false, -1, false, -1),
+                                    MessageHandlerResultType.BINARY);
+                    results.add(result);
+                }
+                if (decoderMatch.getTextDecoders().size() > 0) {
+                    MessageHandlerResult result = new MessageHandlerResult(
+                            new PojoMessageHandlerWholeText(listener, m, 
session,
+                                    endpointConfig,
+                                    decoderMatch.getTextDecoders(), new 
Object[1],
+                                    0, false, -1, -1),
+                                    MessageHandlerResultType.TEXT);
+                    results.add(result);
+                }
             }
         }
 
@@ -447,6 +454,29 @@ public class Util {
         return results;
     }
 
+    private static List<Class<? extends Decoder>> matchDecoders(Class<?> 
target,
+            EndpointConfig endpointConfig, boolean binary) {
+        // More complex case - listener that requires a decoder
+        DecoderMatch decoderMatch;
+        try {
+            List<Class<? extends Decoder>> decoders =
+                    endpointConfig.getDecoders();
+            @SuppressWarnings("unchecked")
+            List<DecoderEntry> decoderEntries = getDecoders(
+                    decoders.toArray(new Class[decoders.size()]));
+            decoderMatch = new DecoderMatch(target, decoderEntries);
+        } catch (DeploymentException e) {
+            throw new IllegalArgumentException(e);
+        }
+        if (binary) {
+            if (decoderMatch.getBinaryDecoders().size() > 0) {
+                return decoderMatch.getBinaryDecoders();
+            }
+        } else if (decoderMatch.getTextDecoders().size() > 0) {
+            return decoderMatch.getTextDecoders();
+        }
+        return null;
+    }
 
     public static void parseExtensionHeader(List<Extension> extensions,
             String header) {
@@ -536,6 +566,15 @@ public class Util {
         }
     }
 
+    private static Method getOnMessagePartialMethod(MessageHandler listener) {
+        try {
+            return listener.getClass().getMethod("onMessage", Object.class, 
Boolean.TYPE);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new IllegalArgumentException(
+                    sm.getString("util.invalidMessageHandler"), e);
+        }
+    }
+
 
     public static class DecoderMatch {
 

Modified: 
tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java?rev=1642282&r1=1642281&r2=1642282&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 
Fri Nov 28 10:33:35 2014
@@ -550,12 +550,16 @@ public abstract class WsRemoteEndpointIm
          * encoders and decoders for this if they wish.
          */
         Encoder encoder = findEncoder(obj);
-
         if (encoder == null && Util.isPrimitive(obj.getClass())) {
             String msg = obj.toString();
             sendStringByCompletion(msg, completion);
             return;
         }
+        if (encoder == null && byte[].class.isAssignableFrom(obj.getClass())) {
+            ByteBuffer msg = ByteBuffer.wrap((byte[]) obj);
+            sendBytesByCompletion(msg, completion);
+            return;
+        }
 
         try {
             if (encoder instanceof Encoder.Text) {



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to