Author: markt Date: Wed Jun 26 09:19:02 2013 New Revision: 1496851 URL: http://svn.apache.org/r1496851 Log: Refactoring in support of fixing BZ 55143
Added: tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResult.java tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResultType.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties tomcat/trunk/java/org/apache/tomcat/websocket/Util.java tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties?rev=1496851&r1=1496850&r2=1496851&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties Wed Jun 26 09:19:02 2013 @@ -72,6 +72,7 @@ wsSession.sendCloseFail=Failed to send c wsSession.invalidHandlerTypePong=A pong message handler must implement MessageHandler.Basic wsSession.removeHandlerFailed=Unable to remove the handler [{0}] as it was not registered with this session wsSession.unknownHandler=Unable to add the message handler [{0}] as it was for the unrecognised type [{1}] +wsSession.unknownHandlerType=Unable to add the message handler [{0}] as it was wrapped as the unrecognised type [{1}] wsWebSocketContainer.asynchronousChannelGroupFail=Unable to create dedicated AsynchronousChannelGroup for WebSocket clients which is required to prevent memory leaks in complex class loader environments like J2EE containers wsWebSocketContainer.asynchronousSocketChannelFail=Unable to open a connection to the server Added: tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResult.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResult.java?rev=1496851&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResult.java (added) +++ tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResult.java Wed Jun 26 09:19:02 2013 @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.websocket; + +import javax.websocket.MessageHandler; + +public class MessageHandlerResult { + + private final MessageHandler handler; + private final MessageHandlerResultType type; + + + public MessageHandlerResult(MessageHandler handler, + MessageHandlerResultType type) { + this.handler = handler; + this.type = type; + } + + + public MessageHandler getHandler() { + return handler; + } + + + public MessageHandlerResultType getType() { + return type; + } +} Added: tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResultType.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResultType.java?rev=1496851&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResultType.java (added) +++ tomcat/trunk/java/org/apache/tomcat/websocket/MessageHandlerResultType.java Wed Jun 26 09:19:02 2013 @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.websocket; + +public enum MessageHandlerResultType { + BINARY, + TEXT, + PONG +} 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=1496851&r1=1496850&r2=1496851&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Wed Jun 26 09:19:02 2013 @@ -19,9 +19,12 @@ package org.apache.tomcat.websocket; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; +import java.util.HashSet; import java.util.Queue; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import javax.websocket.CloseReason.CloseCode; @@ -29,6 +32,7 @@ import javax.websocket.CloseReason.Close import javax.websocket.Decoder; import javax.websocket.Encoder; import javax.websocket.MessageHandler; +import javax.websocket.PongMessage; import org.apache.tomcat.util.res.StringManager; @@ -265,4 +269,42 @@ public class Util { "util.invalidType", value, type.getName())); } } + + + public static Set<MessageHandlerResult> getMessageHandlers( + MessageHandler listener) { + + Type t = Util.getMessageType(listener); + + // Will never be more than 2 types + Set<MessageHandlerResult> results = new HashSet<>(2); + + // Simple cases - handlers already accepts one of the types expected by + // the frame handling code + if (String.class.isAssignableFrom((Class<?>) t)) { + MessageHandlerResult result = + new MessageHandlerResult(listener, + MessageHandlerResultType.TEXT); + results.add(result); + } else if (ByteBuffer.class.isAssignableFrom((Class<?>) t)) { + MessageHandlerResult result = + new MessageHandlerResult(listener, + MessageHandlerResultType.BINARY); + results.add(result); + } else if (PongMessage.class.isAssignableFrom((Class<?>) t)) { + MessageHandlerResult result = + new MessageHandlerResult(listener, + MessageHandlerResultType.PONG); + results.add(result); + } else { + // TODO Decoder handling + } + + if (results.size() == 0) { + throw new IllegalArgumentException( + sm.getString("wsSession.unknownHandler", listener, t)); + } + + return results; + } } Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java?rev=1496851&r1=1496850&r2=1496851&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Wed Jun 26 09:19:02 2013 @@ -17,7 +17,6 @@ package org.apache.tomcat.websocket; import java.io.IOException; -import java.lang.reflect.Type; import java.net.URI; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -152,35 +151,58 @@ public class WsSession implements Sessio checkState(); - Type t = Util.getMessageType(listener); + // Message handlers that require decoders may map to text messages, + // binary messages, both or neither. - if (String.class.isAssignableFrom((Class<?>) t)) { - if (textMessageHandler != null) { - throw new IllegalStateException( - sm.getString("wsSession.duplicateHandlerText")); - } - textMessageHandler = listener; - } else if (ByteBuffer.class.isAssignableFrom((Class<?>) t)) { - if (binaryMessageHandler != null) { - throw new IllegalStateException( - sm.getString("wsSession.duplicateHandlerBinary")); - } - binaryMessageHandler = listener; - } else if (PongMessage.class.isAssignableFrom((Class<?>) t)) { - if (pongMessageHandler != null) { - throw new IllegalStateException( - sm.getString("wsSession.duplicateHandlerPong")); - } - if (listener instanceof MessageHandler.Whole<?>) { - pongMessageHandler = - (MessageHandler.Whole<PongMessage>) listener; - } else { - throw new IllegalStateException( - sm.getString("wsSession.invalidHandlerTypePong")); + // The frame processing code expects binary message handlers to + // accept ByteBuffer + + // Use the POJO message handler wrappers as they are designed to wrap + // arbitrary objects with MessageHandlers and can wrap MessageHandlers + // just as easily. + + Set<MessageHandlerResult> mhResults = Util.getMessageHandlers(listener); + + for (MessageHandlerResult mhResult : mhResults) { + switch (mhResult.getType()) { + case TEXT: { + if (textMessageHandler != null) { + throw new IllegalStateException( + sm.getString("wsSession.duplicateHandlerText")); + } + textMessageHandler = mhResult.getHandler(); + break; + } + case BINARY: { + if (binaryMessageHandler != null) { + throw new IllegalStateException( + sm.getString("wsSession.duplicateHandlerBinary")); + } + binaryMessageHandler = mhResult.getHandler(); + break; + } + case PONG: { + if (pongMessageHandler != null) { + throw new IllegalStateException( + sm.getString("wsSession.duplicateHandlerPong")); + } + MessageHandler handler = mhResult.getHandler(); + if (handler instanceof MessageHandler.Whole<?>) { + pongMessageHandler = + (MessageHandler.Whole<PongMessage>) handler; + } else { + throw new IllegalStateException( + sm.getString("wsSession.invalidHandlerTypePong")); + } + + break; + } + default: { + throw new IllegalArgumentException(sm.getString( + "wsSession.unknownHandlerType", listener, + mhResult.getType())); + } } - } else { - throw new IllegalArgumentException( - sm.getString("wsSession.unknownHandler", listener, t)); } } @@ -208,6 +230,9 @@ public class WsSession implements Sessio if (listener == null) { return; } + + // TODO Handle wrapped listeners + if (listener.equals(textMessageHandler)) { textMessageHandler = null; return; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org