JSR-356 - Fixing @OnMessage message format/decoder detection
This commit is contained in:
parent
9a332cf51d
commit
495d2bcd74
|
@ -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<T extends Annotation, C extends
|
|||
|
||||
public void customizeParamsOnMessage(LinkedList<IJsrParamId> params)
|
||||
{
|
||||
for (Class<? extends Decoder> 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,17 +54,19 @@ public class AnnotatedEndpointScanner<T extends Annotation, C extends EndpointCo
|
|||
paramsOnError = new LinkedList<>();
|
||||
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<? extends Annotation> methodAnnotationClass, Class<?> pojo, Method method)
|
||||
|
|
|
@ -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<? extends Decoder> decoder;
|
||||
private final Class<?> supportedType;
|
||||
|
||||
public JsrParamIdBinaryDecoder(Class<? extends Decoder> 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<? extends Decoder> decoder;
|
||||
private final Class<?> supportedType;
|
||||
|
||||
public JsrParamIdTextDecoder(Class<? extends Decoder> 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;
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@ public class AnnotatedClientEndpointMetadata extends AnnotatedEndpointMetadata<C
|
|||
|
||||
this.endpoint = anno;
|
||||
this.config = new AnnotatedClientEndpointConfig(anno);
|
||||
|
||||
getDecoders().addAll(anno.decoders());
|
||||
getEncoders().addAll(anno.encoders());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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 java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.DateDecoder;
|
||||
|
||||
@ClientEndpoint(decoders =
|
||||
{ DateDecoder.class })
|
||||
public class DateTextSocket
|
||||
{
|
||||
private 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);
|
||||
}
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
this.session = session;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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 static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.MessageType;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.DateDecoder;
|
||||
import org.eclipse.jetty.websocket.jsr356.metadata.DecoderMetadata;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsrParamIdDecoderTest
|
||||
{
|
||||
private OnMessageCallable getOnMessageCallableFrom(Class<?> 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));
|
||||
}
|
||||
}
|
|
@ -45,6 +45,9 @@ public class AnnotatedServerEndpointMetadata extends AnnotatedEndpointMetadata<S
|
|||
|
||||
this.endpoint = anno;
|
||||
this.config = new AnnotatedServerEndpointConfig(websocket,anno);
|
||||
|
||||
getDecoders().addAll(anno.decoders());
|
||||
getEncoders().addAll(anno.encoders());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.lang.reflect.Field;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
|
@ -50,6 +51,7 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.BasicOpenSocket;
|
|||
import org.eclipse.jetty.websocket.jsr356.server.samples.BasicPongMessageSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.BasicTextMessageStringSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.StatelessTextMessageStringSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.beans.DateTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ByteObjectTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ByteTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.CharTextSocket;
|
||||
|
@ -60,6 +62,8 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.FloatObjectT
|
|||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.FloatTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.IntTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.IntegerObjectTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ShortObjectTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.primitives.ShortTextSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderParamSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.StringReturnReaderParamSocket;
|
||||
import org.junit.Assert;
|
||||
|
@ -139,6 +143,10 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest
|
|||
Case.add(data, FloatObjectTextSocket.class, fText, Float.class);
|
||||
Case.add(data, IntTextSocket.class, fText, Integer.TYPE);
|
||||
Case.add(data, IntegerObjectTextSocket.class, fText, Integer.class);
|
||||
Case.add(data, ShortTextSocket.class, fText, Short.TYPE);
|
||||
Case.add(data, ShortObjectTextSocket.class, fText, Short.class);
|
||||
// -- Beans
|
||||
Case.add(data, DateTextSocket.class, fText, Date.class);
|
||||
// -- Reader Events
|
||||
Case.add(data, ReaderParamSocket.class, fText, Reader.class, String.class);
|
||||
Case.add(data, StringReturnReaderParamSocket.class, fText, Reader.class, String.class);
|
||||
|
@ -163,24 +171,25 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest
|
|||
public ServerAnnotatedEndpointScanner_GoodSignaturesTest(Case testcase)
|
||||
{
|
||||
this.testcase = testcase;
|
||||
System.err.printf("Testing signature of %s%n",testcase.pojo.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_Basic() throws Exception
|
||||
{
|
||||
AnnotatedServerEndpointMetadata metadata = new AnnotatedServerEndpointMetadata(container,testcase.pojo);
|
||||
AnnotatedEndpointScanner<ServerEndpoint,ServerEndpointConfig> scanner = new AnnotatedEndpointScanner<>(metadata);
|
||||
AnnotatedEndpointScanner<ServerEndpoint, ServerEndpointConfig> 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));
|
||||
}
|
||||
|
|
|
@ -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<Date>
|
||||
{
|
||||
@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;
|
||||
}
|
||||
}
|
|
@ -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<Date>
|
||||
{
|
||||
@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)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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<Date>
|
||||
{
|
||||
@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;
|
||||
}
|
||||
}
|
|
@ -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<Date>
|
||||
{
|
||||
@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)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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<Date>
|
||||
{
|
||||
@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;
|
||||
}
|
||||
}
|
|
@ -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<Date>
|
||||
{
|
||||
@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)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue