Example usage for org.springframework.messaging.simp.stomp StompConversionException StompConversionException

List of usage examples for org.springframework.messaging.simp.stomp StompConversionException StompConversionException

Introduction

In this page you can find the example usage for org.springframework.messaging.simp.stomp StompConversionException StompConversionException.

Prototype

public StompConversionException(String msg) 

Source Link

Usage

From source file:org.springframework.messaging.simp.stomp.StompDecoder.java

/**
 * Decode a single STOMP frame from the given {@code buffer} into a {@link Message}.
 *///from  www.j  a va2s.  c  o m
@Nullable
private Message<byte[]> decodeMessage(ByteBuffer byteBuffer, @Nullable MultiValueMap<String, String> headers) {
    Message<byte[]> decodedMessage = null;
    skipLeadingEol(byteBuffer);

    // Explicit mark/reset access via Buffer base type for compatibility
    // with covariant return type on JDK 9's ByteBuffer...
    Buffer buffer = byteBuffer;
    buffer.mark();

    String command = readCommand(byteBuffer);
    if (command.length() > 0) {
        StompHeaderAccessor headerAccessor = null;
        byte[] payload = null;
        if (byteBuffer.remaining() > 0) {
            StompCommand stompCommand = StompCommand.valueOf(command);
            headerAccessor = StompHeaderAccessor.create(stompCommand);
            initHeaders(headerAccessor);
            readHeaders(byteBuffer, headerAccessor);
            payload = readPayload(byteBuffer, headerAccessor);
        }
        if (payload != null) {
            if (payload.length > 0) {
                StompCommand stompCommand = headerAccessor.getCommand();
                if (stompCommand != null && !stompCommand.isBodyAllowed()) {
                    throw new StompConversionException(stompCommand + " shouldn't have a payload: length="
                            + payload.length + ", headers=" + headers);
                }
            }
            headerAccessor.updateSimpMessageHeadersFromStompHeaders();
            headerAccessor.setLeaveMutable(true);
            decodedMessage = MessageBuilder.createMessage(payload, headerAccessor.getMessageHeaders());
            if (logger.isTraceEnabled()) {
                logger.trace("Decoded " + headerAccessor.getDetailedLogMessage(payload));
            }
        } else {
            logger.trace("Incomplete frame, resetting input buffer...");
            if (headers != null && headerAccessor != null) {
                String name = NativeMessageHeaderAccessor.NATIVE_HEADERS;
                @SuppressWarnings("unchecked")
                MultiValueMap<String, String> map = (MultiValueMap<String, String>) headerAccessor
                        .getHeader(name);
                if (map != null) {
                    headers.putAll(map);
                }
            }
            buffer.reset();
        }
    } else {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.createForHeartbeat();
        initHeaders(headerAccessor);
        headerAccessor.setLeaveMutable(true);
        decodedMessage = MessageBuilder.createMessage(HEARTBEAT_PAYLOAD, headerAccessor.getMessageHeaders());
        if (logger.isTraceEnabled()) {
            logger.trace("Decoded " + headerAccessor.getDetailedLogMessage(null));
        }
    }

    return decodedMessage;
}

From source file:org.springframework.messaging.simp.stomp.StompDecoder.java

private void readHeaders(ByteBuffer byteBuffer, StompHeaderAccessor headerAccessor) {
    while (true) {
        ByteArrayOutputStream headerStream = new ByteArrayOutputStream(256);
        boolean headerComplete = false;
        while (byteBuffer.hasRemaining()) {
            if (tryConsumeEndOfLine(byteBuffer)) {
                headerComplete = true;//from  ww  w .java  2 s .  co m
                break;
            }
            headerStream.write(byteBuffer.get());
        }
        if (headerStream.size() > 0 && headerComplete) {
            String header = new String(headerStream.toByteArray(), StandardCharsets.UTF_8);
            int colonIndex = header.indexOf(':');
            if (colonIndex <= 0) {
                if (byteBuffer.remaining() > 0) {
                    throw new StompConversionException(
                            "Illegal header: '" + header + "'. A header must be of the form <name>:[<value>].");
                }
            } else {
                String headerName = unescape(header.substring(0, colonIndex));
                String headerValue = unescape(header.substring(colonIndex + 1));
                try {
                    headerAccessor.addNativeHeader(headerName, headerValue);
                } catch (InvalidMimeTypeException ex) {
                    if (byteBuffer.remaining() > 0) {
                        throw ex;
                    }
                }
            }
        } else {
            break;
        }
    }
}

From source file:org.springframework.messaging.simp.stomp.StompDecoder.java

/**
 * See STOMP Spec 1.2:/*from ww w. j av a2 s  .  c  o m*/
 * <a href="http://stomp.github.io/stomp-specification-1.2.html#Value_Encoding">"Value Encoding"</a>.
 */
private String unescape(String inString) {
    StringBuilder sb = new StringBuilder(inString.length());
    int pos = 0; // position in the old string
    int index = inString.indexOf("\\");

    while (index >= 0) {
        sb.append(inString.substring(pos, index));
        if (index + 1 >= inString.length()) {
            throw new StompConversionException("Illegal escape sequence at index " + index + ": " + inString);
        }
        Character c = inString.charAt(index + 1);
        if (c == 'r') {
            sb.append('\r');
        } else if (c == 'n') {
            sb.append('\n');
        } else if (c == 'c') {
            sb.append(':');
        } else if (c == '\\') {
            sb.append('\\');
        } else {
            // should never happen
            throw new StompConversionException("Illegal escape sequence at index " + index + ": " + inString);
        }
        pos = index + 2;
        index = inString.indexOf("\\", pos);
    }

    sb.append(inString.substring(pos));
    return sb.toString();
}

From source file:org.springframework.messaging.simp.stomp.StompDecoder.java

@Nullable
private byte[] readPayload(ByteBuffer byteBuffer, StompHeaderAccessor headerAccessor) {
    Integer contentLength;//from  ww w. j  a va2 s .c  om
    try {
        contentLength = headerAccessor.getContentLength();
    } catch (NumberFormatException ex) {
        if (logger.isWarnEnabled()) {
            logger.warn("Ignoring invalid content-length: '" + headerAccessor);
        }
        contentLength = null;
    }

    if (contentLength != null && contentLength >= 0) {
        if (byteBuffer.remaining() > contentLength) {
            byte[] payload = new byte[contentLength];
            byteBuffer.get(payload);
            if (byteBuffer.get() != 0) {
                throw new StompConversionException("Frame must be terminated with a null octet");
            }
            return payload;
        } else {
            return null;
        }
    } else {
        ByteArrayOutputStream payload = new ByteArrayOutputStream(256);
        while (byteBuffer.remaining() > 0) {
            byte b = byteBuffer.get();
            if (b == 0) {
                return payload.toByteArray();
            } else {
                payload.write(b);
            }
        }
    }
    return null;
}

From source file:org.springframework.messaging.simp.stomp.StompDecoder.java

/**
 * Try to read an EOL incrementing the buffer position if successful.
 * @return whether an EOL was consumed/*from  w ww  . j ava 2s.  co m*/
 */
private boolean tryConsumeEndOfLine(ByteBuffer byteBuffer) {
    if (byteBuffer.remaining() > 0) {
        byte b = byteBuffer.get();
        if (b == '\n') {
            return true;
        } else if (b == '\r') {
            if (byteBuffer.remaining() > 0 && byteBuffer.get() == '\n') {
                return true;
            } else {
                throw new StompConversionException("'\\r' must be followed by '\\n'");
            }
        }
        // Explicit cast for compatibility with covariant return type on JDK 9's ByteBuffer
        ((Buffer) byteBuffer).position(byteBuffer.position() - 1);
    }
    return false;
}

From source file:org.springframework.messaging.simp.stomp.StompProtocolHandler.java

protected void handleConnect(WebSocketSession session, Message<?> message) throws IOException {

    StompHeaderAccessor connectHeaders = StompHeaderAccessor.wrap(message);
    StompHeaderAccessor connectedHeaders = StompHeaderAccessor.create(StompCommand.CONNECTED);

    Set<String> acceptVersions = connectHeaders.getAcceptVersion();
    if (acceptVersions.contains("1.2")) {
        connectedHeaders.setVersion("1.2");
    } else if (acceptVersions.contains("1.1")) {
        connectedHeaders.setVersion("1.1");
    } else if (acceptVersions.isEmpty()) {
        // 1.0/*from  w  w w  .j  a  v  a 2  s .c o  m*/
    } else {
        throw new StompConversionException("Unsupported version '" + acceptVersions + "'");
    }
    connectedHeaders.setHeartbeat(0, 0); // TODO

    Principal principal = session.getPrincipal();
    if (principal != null) {
        connectedHeaders.setNativeHeader(CONNECTED_USER_HEADER, principal.getName());
        connectedHeaders.setNativeHeader(QUEUE_SUFFIX_HEADER, session.getId());

        if (this.queueSuffixResolver != null) {
            String suffix = session.getId();
            this.queueSuffixResolver.addQueueSuffix(principal.getName(), session.getId(), suffix);
        }
    }

    // TODO: security

    Message<?> connectedMessage = MessageBuilder.withPayloadAndHeaders(new byte[0], connectedHeaders).build();
    byte[] bytes = this.stompMessageConverter.fromMessage(connectedMessage);
    session.sendMessage(new TextMessage(new String(bytes, Charset.forName("UTF-8"))));
}

From source file:org.springframework.messaging.simp.stomp.StompWebSocketHandler.java

protected void handleConnect(WebSocketSession session, Message<?> message) throws IOException {

    StompHeaderAccessor connectHeaders = StompHeaderAccessor.wrap(message);
    StompHeaderAccessor connectedHeaders = StompHeaderAccessor.create(StompCommand.CONNECTED);

    Set<String> acceptVersions = connectHeaders.getAcceptVersion();
    if (acceptVersions.contains("1.2")) {
        connectedHeaders.setAcceptVersion("1.2");
    } else if (acceptVersions.contains("1.1")) {
        connectedHeaders.setAcceptVersion("1.1");
    } else if (acceptVersions.isEmpty()) {
        // 1.0/*from   w  w w .  j  ava 2  s  . c  om*/
    } else {
        throw new StompConversionException("Unsupported version '" + acceptVersions + "'");
    }
    connectedHeaders.setHeartbeat(0, 0); // TODO

    Principal principal = session.getPrincipal();
    if (principal != null) {
        connectedHeaders.setNativeHeader(CONNECTED_USER_HEADER, principal.getName());
        connectedHeaders.setNativeHeader(QUEUE_SUFFIX_HEADER, session.getId());

        if (this.queueSuffixResolver != null) {
            String suffix = session.getId();
            this.queueSuffixResolver.addQueueSuffix(principal.getName(), session.getId(), suffix);
        }
    }

    // TODO: security

    Message<?> connectedMessage = MessageBuilder.withPayloadAndHeaders(new byte[0], connectedHeaders).build();
    byte[] bytes = this.stompMessageConverter.fromMessage(connectedMessage);
    session.sendMessage(new TextMessage(new String(bytes, Charset.forName("UTF-8"))));
}