| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 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.io.InputStream; |
| import java.io.Reader; |
| import java.lang.annotation.Annotation; |
| import java.nio.ByteBuffer; |
| import java.util.Map; |
| |
| import javax.websocket.CloseReason; |
| import javax.websocket.DecodeException; |
| import javax.websocket.EndpointConfig; |
| import javax.websocket.OnClose; |
| import javax.websocket.OnError; |
| import javax.websocket.OnMessage; |
| import javax.websocket.OnOpen; |
| import javax.websocket.RemoteEndpoint; |
| |
| import org.eclipse.jetty.util.log.Log; |
| import org.eclipse.jetty.util.log.Logger; |
| import org.eclipse.jetty.websocket.jsr356.JsrSession; |
| |
| /** |
| * The live event methods found for a specific Annotated Endpoint |
| * @param <T> the annotation type |
| * @param <C> the endpoint config type |
| */ |
| public class JsrEvents<T extends Annotation, C extends EndpointConfig> |
| { |
| private static final Logger LOG = Log.getLogger(JsrEvents.class); |
| private final AnnotatedEndpointMetadata<T, C> metadata; |
| |
| /** |
| * Callable for @{@link OnOpen} annotation. |
| */ |
| private final OnOpenCallable onOpen; |
| |
| /** |
| * Callable for @{@link OnClose} annotation |
| */ |
| private final OnCloseCallable onClose; |
| |
| /** |
| * Callable for @{@link OnError} annotation |
| */ |
| private final OnErrorCallable onError; |
| |
| /** |
| * Callable for @{@link OnMessage} annotation dealing with Text Message Format |
| */ |
| private final OnMessageTextCallable onText; |
| |
| /** |
| * Callable for @{@link OnMessage} annotation dealing with Text Streaming Message Format |
| */ |
| private final OnMessageTextStreamCallable onTextStream; |
| |
| /** |
| * Callable for @{@link OnMessage} annotation dealing with Binary Message Format |
| */ |
| private final OnMessageBinaryCallable onBinary; |
| |
| /** |
| * Callable for @{@link OnMessage} annotation dealing with Binary Streaming Message Format |
| */ |
| private final OnMessageBinaryStreamCallable onBinaryStream; |
| |
| /** |
| * Callable for @{@link OnMessage} annotation dealing with Pong Message Format |
| */ |
| private OnMessagePongCallable onPong; |
| |
| /** |
| * The Request Parameters (from resolved javax.websocket.server.PathParam entries) |
| */ |
| private Map<String, String> pathParameters; |
| |
| public JsrEvents(AnnotatedEndpointMetadata<T, C> metadata) |
| { |
| this.metadata = metadata; |
| this.onOpen = (metadata.onOpen == null)?null:new OnOpenCallable(metadata.onOpen); |
| this.onClose = (metadata.onClose == null)?null:new OnCloseCallable(metadata.onClose); |
| this.onError = (metadata.onError == null)?null:new OnErrorCallable(metadata.onError); |
| this.onBinary = (metadata.onBinary == null)?null:new OnMessageBinaryCallable(metadata.onBinary); |
| this.onBinaryStream = (metadata.onBinaryStream == null)?null:new OnMessageBinaryStreamCallable(metadata.onBinaryStream); |
| this.onText = (metadata.onText == null)?null:new OnMessageTextCallable(metadata.onText); |
| this.onTextStream = (metadata.onTextStream == null)?null:new OnMessageTextStreamCallable(metadata.onTextStream); |
| this.onPong = (metadata.onPong == null)?null:new OnMessagePongCallable(metadata.onPong); |
| } |
| |
| public void callBinary(RemoteEndpoint.Async endpoint, Object websocket, ByteBuffer buf, boolean fin) throws DecodeException |
| { |
| if (onBinary == null) |
| { |
| return; |
| } |
| |
| Object ret = onBinary.call(websocket,buf,fin); |
| if (ret != null) |
| { |
| if (LOG.isDebugEnabled()) |
| { |
| LOG.debug("returning: {}",ret); |
| } |
| endpoint.sendObject(ret); |
| } |
| } |
| |
| public void callBinaryStream(RemoteEndpoint.Async endpoint, Object websocket, InputStream stream) throws DecodeException, IOException |
| { |
| if (onBinaryStream == null) |
| { |
| return; |
| } |
| |
| Object ret = onBinaryStream.call(websocket,stream); |
| if (ret != null) |
| { |
| if (LOG.isDebugEnabled()) |
| { |
| LOG.debug("returning: {}",ret); |
| } |
| endpoint.sendObject(ret); |
| } |
| } |
| |
| public void callClose(Object websocket, CloseReason close) |
| { |
| if (onClose == null) |
| { |
| return; |
| } |
| onClose.call(websocket,close); |
| } |
| |
| public void callError(Object websocket, Throwable cause) |
| { |
| if (onError == null) |
| { |
| LOG.warn("Unable to report throwable to websocket (no @OnError handler declared): " + websocket.getClass().getName(), cause); |
| return; |
| } |
| onError.call(websocket,cause); |
| } |
| |
| public void callOpen(Object websocket, EndpointConfig config) |
| { |
| if (onOpen == null) |
| { |
| return; |
| } |
| onOpen.call(websocket,config); |
| } |
| |
| public void callPong(RemoteEndpoint.Async endpoint, Object websocket, ByteBuffer pong) |
| { |
| if (onPong == null) |
| { |
| return; |
| } |
| |
| Object ret = onPong.call(websocket,pong); |
| if (ret != null) |
| { |
| if (LOG.isDebugEnabled()) |
| { |
| LOG.debug("returning: {}",ret); |
| } |
| endpoint.sendObject(ret); |
| } |
| } |
| |
| public void callText(RemoteEndpoint.Async endpoint, Object websocket, String text, boolean fin) throws DecodeException |
| { |
| if (onText == null) |
| { |
| return; |
| } |
| Object ret = onText.call(websocket,text,fin); |
| if (ret != null) |
| { |
| if (LOG.isDebugEnabled()) |
| { |
| LOG.debug("returning: {}",ret); |
| } |
| endpoint.sendObject(ret); |
| } |
| } |
| |
| public void callTextStream(RemoteEndpoint.Async endpoint, Object websocket, Reader reader) throws DecodeException, IOException |
| { |
| if (onTextStream == null) |
| { |
| return; |
| } |
| Object ret = onTextStream.call(websocket,reader); |
| if (ret != null) |
| { |
| if (LOG.isDebugEnabled()) |
| { |
| LOG.debug("returning: {}",ret); |
| } |
| endpoint.sendObject(ret); |
| } |
| } |
| |
| public AnnotatedEndpointMetadata<T, C> getMetadata() |
| { |
| return metadata; |
| } |
| |
| public boolean hasBinary() |
| { |
| return (onBinary != null); |
| } |
| |
| public boolean hasBinaryStream() |
| { |
| return (onBinaryStream != null); |
| } |
| |
| public boolean hasText() |
| { |
| return (onText != null); |
| } |
| |
| public boolean hasTextStream() |
| { |
| return (onTextStream != null); |
| } |
| |
| public void init(JsrSession session) |
| { |
| session.setPathParameters(pathParameters); |
| |
| if (onOpen != null) |
| { |
| onOpen.init(session); |
| } |
| if (onClose != null) |
| { |
| onClose.init(session); |
| } |
| if (onError != null) |
| { |
| onError.init(session); |
| } |
| if (onText != null) |
| { |
| onText.init(session); |
| } |
| if (onTextStream != null) |
| { |
| onTextStream.init(session); |
| } |
| if (onBinary != null) |
| { |
| onBinary.init(session); |
| } |
| if (onBinaryStream != null) |
| { |
| onBinaryStream.init(session); |
| } |
| if (onPong != null) |
| { |
| onPong.init(session); |
| } |
| } |
| |
| public boolean isBinaryPartialSupported() |
| { |
| if (onBinary == null) |
| { |
| return false; |
| } |
| return onBinary.isPartialMessageSupported(); |
| } |
| |
| public boolean isTextPartialSupported() |
| { |
| if (onText == null) |
| { |
| return false; |
| } |
| return onText.isPartialMessageSupported(); |
| } |
| |
| public void setPathParameters(Map<String, String> pathParameters) |
| { |
| this.pathParameters = pathParameters; |
| } |
| } |