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: [email protected]
For additional commands, e-mail: [email protected]