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