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

Reply via email to