001/*
002 * Copyright 2002-2014 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.util.Assert;
020import org.springframework.util.ObjectUtils;
021
022/**
023 * A message that can be handled or sent on a WebSocket connection.
024 *
025 * @author Rossen Stoyanchev
026 * @since 4.0
027 */
028public abstract class AbstractWebSocketMessage<T> implements WebSocketMessage<T> {
029
030        private final T payload;
031
032        private final boolean last;
033
034
035        /**
036         * Create a new WebSocket message with the given payload.
037         * @param payload the non-null payload
038         */
039        AbstractWebSocketMessage(T payload) {
040                this(payload, true);
041        }
042
043        /**
044         * Create a new WebSocket message given payload representing the full or partial
045         * message content. When the {@code isLast} boolean flag is set to {@code false}
046         * the message is sent as partial content and more partial messages will be
047         * expected until the boolean flag is set to {@code true}.
048         * @param payload the non-null payload
049         * @param isLast if the message is the last of a series of partial messages
050         */
051        AbstractWebSocketMessage(T payload, boolean isLast) {
052                Assert.notNull(payload, "payload must not be null");
053                this.payload = payload;
054                this.last = isLast;
055        }
056
057
058        /**
059         * Return the message payload, never be {@code null}.
060         */
061        public T getPayload() {
062                return this.payload;
063        }
064
065        /**
066         * Whether this is the last part of a message sent as a series of partial messages.
067         */
068        public boolean isLast() {
069                return this.last;
070        }
071
072
073        @Override
074        public boolean equals(Object other) {
075                if (this == other) {
076                        return true;
077                }
078                if (!(other instanceof AbstractWebSocketMessage)) {
079                        return false;
080                }
081                AbstractWebSocketMessage<?> otherMessage = (AbstractWebSocketMessage<?>) other;
082                return ObjectUtils.nullSafeEquals(this.payload, otherMessage.payload);
083        }
084
085        @Override
086        public int hashCode() {
087                return ObjectUtils.nullSafeHashCode(this.payload);
088        }
089
090        @Override
091        public String toString() {
092                return getClass().getSimpleName() + " payload=[" + toStringPayload() +
093                                "], byteCount=" + getPayloadLength() + ", last=" + isLast() + "]";
094        }
095
096        protected abstract String toStringPayload();
097
098}