Author: remm
Date: Tue Dec  2 21:16:51 2014
New Revision: 1643008

URL: http://svn.apache.org/r1643008
Log:
Websockets annotations can be located on superclasses, and also improve 
duplicates detection.

Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
    tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.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=1643008&r1=1643007&r2=1643008&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Tue Dec  2 21:16:51 
2014
@@ -576,9 +576,10 @@ public class Util {
                 new ArrayList<>();
         private final List<Class<? extends Decoder>> binaryDecoders =
                 new ArrayList<>();
-
+        private final Class<?> target;
 
         public DecoderMatch(Class<?> target, List<DecoderEntry> 
decoderEntries) {
+            this.target = target;
             for (DecoderEntry decoderEntry : decoderEntries) {
                 if (decoderEntry.getClazz().isAssignableFrom(target)) {
                     if (Binary.class.isAssignableFrom(
@@ -624,6 +625,11 @@ public class Util {
         }
 
 
+        public Class<?> getTarget() {
+            return target;
+        }
+
+
         public boolean hasMatches() {
             return (textDecoders.size() > 0) || (binaryDecoders.size() > 0);
         }

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=1643008&r1=1643007&r2=1643008&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java 
Tue Dec  2 21:16:51 2014
@@ -22,6 +22,7 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -64,7 +65,7 @@ public class PojoMethodMapping {
     private final PojoPathParam[] onOpenParams;
     private final PojoPathParam[] onCloseParams;
     private final PojoPathParam[] onErrorParams;
-    private final Set<MessageHandlerInfo> onMessage = new HashSet<>();
+    private final List<MessageHandlerInfo> onMessage = new ArrayList<>();
     private final String wsPath;
 
 
@@ -78,43 +79,56 @@ public class PojoMethodMapping {
         Method open = null;
         Method close = null;
         Method error = null;
-        for (Method method : clazzPojo.getDeclaredMethods()) {
-            if (method.getAnnotation(OnOpen.class) != null) {
-                checkPublic(method);
-                if (open == null) {
-                    open = method;
-                } else {
-                    // Duplicate annotation
-                    throw new DeploymentException(sm.getString(
-                            "pojoMethodMapping.duplicateAnnotation",
-                            OnOpen.class, clazzPojo));
-                }
-            } else if (method.getAnnotation(OnClose.class) != null) {
-                checkPublic(method);
-                if (close == null) {
-                    close = method;
-                } else {
-                    // Duplicate annotation
-                    throw new DeploymentException(sm.getString(
-                            "pojoMethodMapping.duplicateAnnotation",
-                            OnClose.class, clazzPojo));
-                }
-            } else if (method.getAnnotation(OnError.class) != null) {
-                checkPublic(method);
-                if (error == null) {
-                    error = method;
+        Class<?> currentClazz = clazzPojo;
+        while (!currentClazz.equals(Object.class)) {
+            for (Method method : currentClazz.getDeclaredMethods()) {
+                if (method.getAnnotation(OnOpen.class) != null) {
+                    checkPublic(method);
+                    if (open == null) {
+                        open = method;
+                    } else {
+                        // Duplicate annotation
+                        throw new DeploymentException(sm.getString(
+                                "pojoMethodMapping.duplicateAnnotation",
+                                OnOpen.class, clazzPojo));
+                    }
+                } else if (method.getAnnotation(OnClose.class) != null) {
+                    checkPublic(method);
+                    if (close == null) {
+                        close = method;
+                    } else {
+                        // Duplicate annotation
+                        throw new DeploymentException(sm.getString(
+                                "pojoMethodMapping.duplicateAnnotation",
+                                OnClose.class, clazzPojo));
+                    }
+                } else if (method.getAnnotation(OnError.class) != null) {
+                    checkPublic(method);
+                    if (error == null) {
+                        error = method;
+                    } else {
+                        // Duplicate annotation
+                        throw new DeploymentException(sm.getString(
+                                "pojoMethodMapping.duplicateAnnotation",
+                                OnError.class, clazzPojo));
+                    }
+                } else if (method.getAnnotation(OnMessage.class) != null) {
+                    checkPublic(method);
+                    MessageHandlerInfo messageHandler = new 
MessageHandlerInfo(method, decoders);
+                    for (MessageHandlerInfo otherMessageHandler : onMessage) {
+                        if (messageHandler.equals(otherMessageHandler)) {
+                            // Duplicate annotation
+                            throw new DeploymentException(sm.getString(
+                                    "pojoMethodMapping.duplicateAnnotation",
+                                    OnMessage.class, clazzPojo));
+                        }
+                    }
+                    onMessage.add(messageHandler);
                 } else {
-                    // Duplicate annotation
-                    throw new DeploymentException(sm.getString(
-                            "pojoMethodMapping.duplicateAnnotation",
-                            OnError.class, clazzPojo));
+                    // Method not annotated
                 }
-            } else if (method.getAnnotation(OnMessage.class) != null) {
-                checkPublic(method);
-                onMessage.add(new MessageHandlerInfo(method, decoders));
-            } else {
-                // Method not annotated
             }
+            currentClazz = currentClazz.getSuperclass();
         }
         this.onOpen = open;
         this.onClose = close;
@@ -288,6 +302,7 @@ public class PojoMethodMapping {
         private int indexInputStream = -1;
         private int indexReader = -1;
         private int indexPrimitive = -1;
+        private Class<?> primitiveType = null;
         private Map<Integer,PojoPathParam> indexPathParams = new HashMap<>();
         private int indexPayload = -1;
         private DecoderMatch decoderMatch = null;
@@ -366,6 +381,7 @@ public class PojoMethodMapping {
                 } else if (Util.isPrimitive(types[i])) {
                     if (indexPrimitive == -1) {
                         indexPrimitive = i;
+                        primitiveType = types[i];
                     } else {
                         throw new IllegalArgumentException(sm.getString(
                                 "pojoMethodMapping.duplicateMessageParam",
@@ -470,6 +486,7 @@ public class PojoMethodMapping {
                 // The boolean we found is a payload, not a last flag
                 indexPayload = indexBoolean;
                 indexPrimitive = indexBoolean;
+                primitiveType = Boolean.TYPE;
                 indexBoolean = -1;
             }
             if (indexPayload == -1) {
@@ -503,6 +520,42 @@ public class PojoMethodMapping {
         }
 
 
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null || !(obj instanceof MessageHandlerInfo)) {
+                return false;
+            }
+            MessageHandlerInfo otherHandler = (MessageHandlerInfo) obj;
+            if (indexByteArray >= 0 && otherHandler.indexByteArray >= 0) {
+                return true;
+            }
+            if (indexByteBuffer >= 0 && otherHandler.indexByteBuffer >= 0) {
+                return true;
+            }
+            if (indexInputStream >= 0 && otherHandler.indexInputStream >= 0) {
+                return true;
+            }
+            if (indexPong >= 0 && otherHandler.indexPong >= 0) {
+                return true;
+            }
+            if (indexPrimitive >= 0 && otherHandler.indexPrimitive >= 0
+                    && primitiveType == otherHandler.primitiveType) {
+                return true;
+            }
+            if (indexReader >= 0 && otherHandler.indexReader >= 0) {
+                return true;
+            }
+            if (indexString >= 0 && otherHandler.indexString >= 0) {
+                return true;
+            }
+            if (decoderMatch != null && otherHandler.decoderMatch != null
+                    && 
decoderMatch.getTarget().equals(otherHandler.decoderMatch.getTarget())) {
+                return true;
+            }
+            return false;
+        }
+
+
         public Set<MessageHandler> getMessageHandlers(Object pojo,
                 Map<String,String> pathParameters, Session session,
                 EndpointConfig config) {



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

Reply via email to