001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.socket;
018
019import org.springframework.lang.Nullable;
020import org.springframework.util.Assert;
021import org.springframework.util.ObjectUtils;
022
023/**
024 * A message that can be handled or sent on a WebSocket connection.
025 *
026 * @author Rossen Stoyanchev
027 * @since 4.0
028 * @param <T> the payload type
029 */
030public abstract class AbstractWebSocketMessage<T> implements WebSocketMessage<T> {
031
032        private final T payload;
033
034        private final boolean last;
035
036
037        /**
038         * Create a new WebSocket message with the given payload.
039         * @param payload the non-null payload
040         */
041        AbstractWebSocketMessage(T payload) {
042                this(payload, true);
043        }
044
045        /**
046         * Create a new WebSocket message given payload representing the full or partial
047         * message content. When the {@code isLast} boolean flag is set to {@code false}
048         * the message is sent as partial content and more partial messages will be
049         * expected until the boolean flag is set to {@code true}.
050         * @param payload the non-null payload
051         * @param isLast if the message is the last of a series of partial messages
052         */
053        AbstractWebSocketMessage(T payload, boolean isLast) {
054                Assert.notNull(payload, "payload must not be null");
055                this.payload = payload;
056                this.last = isLast;
057        }
058
059
060        /**
061         * Return the message payload (never {@code null}).
062         */
063        @Override
064        public T getPayload() {
065                return this.payload;
066        }
067
068        /**
069         * Whether this is the last part of a message sent as a series of partial messages.
070         */
071        @Override
072        public boolean isLast() {
073                return this.last;
074        }
075
076
077        @Override
078        public boolean equals(@Nullable Object other) {
079                if (this == other) {
080                        return true;
081                }
082                if (!(other instanceof AbstractWebSocketMessage)) {
083                        return false;
084                }
085                AbstractWebSocketMessage<?> otherMessage = (AbstractWebSocketMessage<?>) other;
086                return ObjectUtils.nullSafeEquals(this.payload, otherMessage.payload);
087        }
088
089        @Override
090        public int hashCode() {
091                return ObjectUtils.nullSafeHashCode(this.payload);
092        }
093
094        @Override
095        public String toString() {
096                return getClass().getSimpleName() + " payload=[" + toStringPayload() +
097                                "], byteCount=" + getPayloadLength() + ", last=" + isLast() + "]";
098        }
099
100        protected abstract String toStringPayload();
101
102}