From 495d2bcd74df0249ad8cf0f646e3373b8523e652 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 11 Jul 2013 11:00:23 -0700 Subject: [PATCH] JSR-356 - Fixing @OnMessage message format/decoder detection --- .../AnnotatedEndpointMetadata.java | 35 +-------- .../annotations/AnnotatedEndpointScanner.java | 14 ++-- .../annotations/JsrParamIdBinaryDecoder.java | 53 ------------- .../jsr356/annotations/JsrParamIdDecoder.java | 78 +++++++++++++++++++ .../annotations/JsrParamIdTextDecoder.java | 53 ------------- .../jsr356/annotations/OnMessageCallable.java | 4 +- .../AnnotatedClientEndpointMetadata.java | 3 + .../jsr356/annotations/DateTextSocket.java | 57 ++++++++++++++ .../annotations/JsrParamIdDecoderTest.java | 57 ++++++++++++++ .../AnnotatedServerEndpointMetadata.java | 3 + ...tedEndpointScanner_GoodSignaturesTest.java | 17 +++- .../server/samples/beans/DateDecoder.java | 62 +++++++++++++++ .../server/samples/beans/DateEncoder.java | 48 ++++++++++++ .../server/samples/beans/DateTextSocket.java | 69 ++++++++++++++++ .../server/samples/beans/DateTimeDecoder.java | 62 +++++++++++++++ .../server/samples/beans/DateTimeEncoder.java | 48 ++++++++++++ .../server/samples/beans/TimeDecoder.java | 62 +++++++++++++++ .../server/samples/beans/TimeEncoder.java | 48 ++++++++++++ .../events/annotated/CallableMethod.java | 3 + 19 files changed, 627 insertions(+), 149 deletions(-) delete mode 100644 jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdBinaryDecoder.java create mode 100644 jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdDecoder.java delete mode 100644 jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdTextDecoder.java create mode 100644 jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/annotations/DateTextSocket.java create mode 100644 jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdDecoderTest.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateDecoder.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateEncoder.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTextSocket.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeDecoder.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeEncoder.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeDecoder.java create mode 100644 jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeEncoder.java diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointMetadata.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointMetadata.java index 9aa6f905247..776e5effb0e 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointMetadata.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointMetadata.java @@ -21,17 +21,16 @@ package org.eclipse.jetty.websocket.jsr356.annotations; import java.lang.annotation.Annotation; import java.util.LinkedList; -import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; +import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadata; import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadataSet; import org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadataSet; import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata; -import org.eclipse.jetty.websocket.jsr356.utils.ReflectUtils; /** * Static reference to a specific annotated classes metadata. @@ -104,37 +103,9 @@ public abstract class AnnotatedEndpointMetadata params) { - for (Class decoder : getDecoders().getList()) + for (DecoderMetadata metadata : decoders) { - if (Decoder.Text.class.isAssignableFrom(decoder)) - { - Class type = ReflectUtils.findGenericClassFor(decoder,Decoder.Text.class); - params.add(new JsrParamIdTextDecoder(decoder,type)); - continue; - } - - if (Decoder.TextStream.class.isAssignableFrom(decoder)) - { - Class type = ReflectUtils.findGenericClassFor(decoder,Decoder.TextStream.class); - params.add(new JsrParamIdTextDecoder(decoder,type)); - continue; - } - - if (Decoder.Binary.class.isAssignableFrom(decoder)) - { - Class type = ReflectUtils.findGenericClassFor(decoder,Decoder.Binary.class); - params.add(new JsrParamIdBinaryDecoder(decoder,type)); - continue; - } - - if (Decoder.BinaryStream.class.isAssignableFrom(decoder)) - { - Class type = ReflectUtils.findGenericClassFor(decoder,Decoder.BinaryStream.class); - params.add(new JsrParamIdBinaryDecoder(decoder,type)); - continue; - } - - throw new IllegalStateException("Invalid Decoder: " + decoder); + params.add(new JsrParamIdDecoder(metadata)); } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointScanner.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointScanner.java index 81c4b32a0d0..e0957f7c6f2 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointScanner.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/AnnotatedEndpointScanner.java @@ -54,17 +54,19 @@ public class AnnotatedEndpointScanner(); paramsOnMessage = new LinkedList<>(); - paramsOnOpen.add(JsrParamIdOnOpen.INSTANCE); metadata.customizeParamsOnOpen(paramsOnOpen); - paramsOnClose.add(JsrParamIdOnClose.INSTANCE); - metadata.customizeParamsOnClose(paramsOnClose); - paramsOnError.add(JsrParamIdOnError.INSTANCE); - metadata.customizeParamsOnError(paramsOnError); + paramsOnOpen.add(JsrParamIdOnOpen.INSTANCE); + metadata.customizeParamsOnClose(paramsOnClose); + paramsOnClose.add(JsrParamIdOnClose.INSTANCE); + + metadata.customizeParamsOnError(paramsOnError); + paramsOnError.add(JsrParamIdOnError.INSTANCE); + + metadata.customizeParamsOnMessage(paramsOnMessage); paramsOnMessage.add(JsrParamIdBinary.INSTANCE); paramsOnMessage.add(JsrParamIdText.INSTANCE); paramsOnMessage.add(JsrParamIdPong.INSTANCE); - metadata.customizeParamsOnMessage(paramsOnMessage); } private void assertNotDuplicate(JsrCallable callable, Class methodAnnotationClass, Class pojo, Method method) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdBinaryDecoder.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdBinaryDecoder.java deleted file mode 100644 index edcbb90753e..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdBinaryDecoder.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.jsr356.annotations; - -import javax.websocket.Decoder; -import javax.websocket.OnMessage; - -import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException; -import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role; - -/** - * Param handling for Binary @{@link OnMessage} parameters declared as {@link Decoder}s of type {@link Decoder.Binary} or {@link Decoder.BinaryStream} - */ -public class JsrParamIdBinaryDecoder extends JsrParamIdOnMessage implements IJsrParamId -{ - private final Class decoder; - private final Class supportedType; - - public JsrParamIdBinaryDecoder(Class decoder, Class supportedType) - { - this.decoder = decoder; - this.supportedType = supportedType; - } - - @Override - public boolean process(Param param, JsrCallable callable) throws InvalidSignatureException - { - if (param.type.isAssignableFrom(supportedType)) - { - assertPartialMessageSupportDisabled(param,callable); - param.bind(Role.MESSAGE_BINARY); - callable.setDecoderClass(decoder); - return true; - } - return false; - } -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdDecoder.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdDecoder.java new file mode 100644 index 00000000000..8942eec6396 --- /dev/null +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdDecoder.java @@ -0,0 +1,78 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.annotations; + +import javax.websocket.Decoder; +import javax.websocket.OnMessage; + +import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException; +import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role; +import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadata; + +/** + * Param handling for Text or Binary @{@link OnMessage} parameters declared as {@link Decoder}s + */ +public class JsrParamIdDecoder extends JsrParamIdOnMessage implements IJsrParamId +{ + private final DecoderMetadata metadata; + + public JsrParamIdDecoder(DecoderMetadata metadata) + { + this.metadata = metadata; + } + + @Override + public boolean process(Param param, JsrCallable callable) throws InvalidSignatureException + { + if (param.type.isAssignableFrom(metadata.getObjectType())) + { + assertPartialMessageSupportDisabled(param,callable); + + switch (metadata.getMessageType()) + { + case TEXT: + if (metadata.isStreamed()) + { + param.bind(Role.MESSAGE_TEXT_STREAM); + } + else + { + param.bind(Role.MESSAGE_TEXT); + } + break; + case BINARY: + if (metadata.isStreamed()) + { + param.bind(Role.MESSAGE_BINARY_STREAM); + } + else + { + param.bind(Role.MESSAGE_BINARY); + } + break; + case PONG: + param.bind(Role.MESSAGE_PONG); + break; + } + callable.setDecoderClass(metadata.getCoderClass()); + return true; + } + return false; + } +} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdTextDecoder.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdTextDecoder.java deleted file mode 100644 index 405e29bb4b7..00000000000 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/JsrParamIdTextDecoder.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.jsr356.annotations; - -import javax.websocket.Decoder; -import javax.websocket.OnMessage; - -import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException; -import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role; - -/** - * Param handling for Text @{@link OnMessage} parameters declared as {@link Decoder}s of type {@link Decoder.Text} or {@link Decoder.TextStream} - */ -public class JsrParamIdTextDecoder extends JsrParamIdOnMessage implements IJsrParamId -{ - private final Class decoder; - private final Class supportedType; - - public JsrParamIdTextDecoder(Class decoder, Class supportedType) - { - this.decoder = decoder; - this.supportedType = supportedType; - } - - @Override - public boolean process(Param param, JsrCallable callable) throws InvalidSignatureException - { - if (param.type.isAssignableFrom(supportedType)) - { - assertPartialMessageSupportDisabled(param,callable); - param.bind(Role.MESSAGE_TEXT_STREAM); // TODO: is this sane? for Text & TextStream ? - callable.setDecoderClass(decoder); - return true; - } - return false; - } -} diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageCallable.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageCallable.java index dfbb65882bb..d6e246c5a3c 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageCallable.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageCallable.java @@ -28,6 +28,7 @@ import org.eclipse.jetty.websocket.jsr356.EncoderFactory; import org.eclipse.jetty.websocket.jsr356.InitException; import org.eclipse.jetty.websocket.jsr356.JsrSession; import org.eclipse.jetty.websocket.jsr356.utils.MethodUtils; +import org.eclipse.jetty.websocket.jsr356.utils.ReflectUtils; public class OnMessageCallable extends JsrCallable { @@ -119,7 +120,8 @@ public class OnMessageCallable extends JsrCallable if (idxMessageObject < 0) { StringBuilder err = new StringBuilder(); - err.append("A message type must be specified [TEXT, BINARY, DECODER, or PONG]"); + err.append("A message type must be specified [TEXT, BINARY, DECODER, or PONG] : "); + err.append(ReflectUtils.toString(pojo,method)); throw new InvalidSignatureException(err.toString()); } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/client/AnnotatedClientEndpointMetadata.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/client/AnnotatedClientEndpointMetadata.java index d367bf6343d..70f6d53bc17 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/client/AnnotatedClientEndpointMetadata.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/client/AnnotatedClientEndpointMetadata.java @@ -43,6 +43,9 @@ public class AnnotatedClientEndpointMetadata extends AnnotatedEndpointMetadata clazz, String methodName) + { + for (Method method : clazz.getMethods()) + { + if (method.getName().equals(methodName)) + { + return new OnMessageCallable(clazz,method); + } + } + return null; + } + + @Test + public void testMatchDateDecoder() + { + DecoderMetadata metadata = new DecoderMetadata(DateDecoder.class,Date.class,MessageType.TEXT,false); + JsrParamIdDecoder paramId = new JsrParamIdDecoder(metadata); + + OnMessageCallable callable = getOnMessageCallableFrom(DateTextSocket.class,"onMessage"); + Param param = new Param(0,Date.class); + + Assert.assertThat("Match for Decoder",paramId.process(param,callable),is(true)); + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java index 68f2772bc90..ac45facde59 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointMetadata.java @@ -45,6 +45,9 @@ public class AnnotatedServerEndpointMetadata extends AnnotatedEndpointMetadata scanner = new AnnotatedEndpointScanner<>(metadata); + AnnotatedEndpointScanner scanner = new AnnotatedEndpointScanner<>(metadata); scanner.scan(); Assert.assertThat("Metadata",metadata,notNullValue()); - JsrCallable cm = (JsrCallable)testcase.metadataField.get(metadata); - Assert.assertThat(testcase.metadataField.toString(),cm,notNullValue()); + JsrCallable method = (JsrCallable)testcase.metadataField.get(metadata); + Assert.assertThat(testcase.metadataField.toString(),method,notNullValue()); int len = testcase.expectedParameters.length; for (int i = 0; i < len; i++) { Class expectedParam = testcase.expectedParameters[i]; - Class actualParam = cm.getParamTypes()[i]; + Class actualParam = method.getParamTypes()[i]; Assert.assertTrue("Parameter[" + i + "] - expected:[" + expectedParam + "], actual:[" + actualParam + "]",actualParam.equals(expectedParam)); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateDecoder.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateDecoder.java new file mode 100644 index 00000000000..b2ab7e576fe --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateDecoder.java @@ -0,0 +1,62 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +/** + * Decode Date + */ +public class DateDecoder implements Decoder.Text +{ + @Override + public Date decode(String s) throws DecodeException + { + try + { + return new SimpleDateFormat("yyyy.MM.dd").parse(s); + } + catch (ParseException e) + { + throw new DecodeException(s,e.getMessage(),e); + } + } + + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } + + @Override + public boolean willDecode(String s) + { + return true; + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateEncoder.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateEncoder.java new file mode 100644 index 00000000000..4171d3e9593 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateEncoder.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +/** + * Encode Date + */ +public class DateEncoder implements Encoder.Text +{ + @Override + public void destroy() + { + } + + @Override + public String encode(Date object) throws EncodeException + { + return new SimpleDateFormat("yyyy.MM.dd").format(object); + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTextSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTextSocket.java new file mode 100644 index 00000000000..07644d017ca --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTextSocket.java @@ -0,0 +1,69 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.jsr356.server.StackUtil; + +@ServerEndpoint(value = "/echo/beans/date", decoders = +{ DateDecoder.class }) +public class DateTextSocket +{ + private static final Logger LOG = Log.getLogger(DateTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(Date d) throws IOException + { + if (d == null) + { + session.getAsyncRemote().sendText("Error: Date is null"); + } + else + { + String msg = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(d); + session.getAsyncRemote().sendText(msg); + } + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error",cause); + session.getBasicRemote().sendText("Exception: " + StackUtil.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeDecoder.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeDecoder.java new file mode 100644 index 00000000000..56892dc0f45 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeDecoder.java @@ -0,0 +1,62 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +/** + * Decode Date and Time + */ +public class DateTimeDecoder implements Decoder.Text +{ + @Override + public Date decode(String s) throws DecodeException + { + try + { + return new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z").parse(s); + } + catch (ParseException e) + { + throw new DecodeException(s,e.getMessage(),e); + } + } + + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } + + @Override + public boolean willDecode(String s) + { + return true; + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeEncoder.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeEncoder.java new file mode 100644 index 00000000000..67dcf224dd9 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/DateTimeEncoder.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +/** + * Encode Date + */ +public class DateTimeEncoder implements Encoder.Text +{ + @Override + public void destroy() + { + } + + @Override + public String encode(Date object) throws EncodeException + { + return new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z").format(object); + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeDecoder.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeDecoder.java new file mode 100644 index 00000000000..326804cf9e8 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeDecoder.java @@ -0,0 +1,62 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +/** + * Decode Time + */ +public class TimeDecoder implements Decoder.Text +{ + @Override + public Date decode(String s) throws DecodeException + { + try + { + return new SimpleDateFormat("HH:mm:ss z").parse(s); + } + catch (ParseException e) + { + throw new DecodeException(s,e.getMessage(),e); + } + } + + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } + + @Override + public boolean willDecode(String s) + { + return true; + } +} diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeEncoder.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeEncoder.java new file mode 100644 index 00000000000..87e49ba0373 --- /dev/null +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/beans/TimeEncoder.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.jsr356.server.samples.beans; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +/** + * Encode Time + */ +public class TimeEncoder implements Encoder.Text +{ + @Override + public void destroy() + { + } + + @Override + public String encode(Date object) throws EncodeException + { + return new SimpleDateFormat("HH:mm:ss z").format(object); + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/annotated/CallableMethod.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/annotated/CallableMethod.java index dfee4cbcf9a..503f909bc52 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/annotated/CallableMethod.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/annotated/CallableMethod.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.common.events.annotated; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Objects; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -37,6 +38,8 @@ public class CallableMethod public CallableMethod(Class pojo, Method method) { + Objects.requireNonNull(pojo, "Pojo cannot be null"); + Objects.requireNonNull(method, "Method cannot be null"); this.pojo = pojo; this.method = method; this.paramTypes = method.getParameterTypes();