001/*
002 * Copyright 2002-2016 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.handler;
018
019import java.io.IOException;
020import java.net.InetSocketAddress;
021import java.net.URI;
022import java.security.Principal;
023import java.util.List;
024import java.util.Map;
025
026import org.springframework.http.HttpHeaders;
027import org.springframework.lang.Nullable;
028import org.springframework.util.Assert;
029import org.springframework.web.socket.CloseStatus;
030import org.springframework.web.socket.WebSocketExtension;
031import org.springframework.web.socket.WebSocketMessage;
032import org.springframework.web.socket.WebSocketSession;
033
034/**
035 * Wraps another {@link org.springframework.web.socket.WebSocketSession} instance
036 * and delegates to it.
037 *
038 * <p>Also provides a {@link #getDelegate()} method to return the decorated session
039 * as well as a {@link #getLastSession()} method to go through all nested delegates
040 * and return the "last" session.
041 *
042 * @author Rossen Stoyanchev
043 * @since 4.0.3
044 */
045public class WebSocketSessionDecorator implements WebSocketSession {
046
047        private final WebSocketSession delegate;
048
049
050        public WebSocketSessionDecorator(WebSocketSession session) {
051                Assert.notNull(session, "Delegate WebSocketSessionSession is required");
052                this.delegate = session;
053        }
054
055
056        public WebSocketSession getDelegate() {
057                return this.delegate;
058        }
059
060        public WebSocketSession getLastSession() {
061                WebSocketSession result = this.delegate;
062                while (result instanceof WebSocketSessionDecorator) {
063                        result = ((WebSocketSessionDecorator) result).getDelegate();
064                }
065                return result;
066        }
067
068        public static WebSocketSession unwrap(WebSocketSession session) {
069                if (session instanceof WebSocketSessionDecorator) {
070                        return ((WebSocketSessionDecorator) session).getLastSession();
071                }
072                else {
073                        return session;
074                }
075        }
076
077        @Override
078        public String getId() {
079                return this.delegate.getId();
080        }
081
082        @Override
083        @Nullable
084        public URI getUri() {
085                return this.delegate.getUri();
086        }
087
088        @Override
089        public HttpHeaders getHandshakeHeaders() {
090                return this.delegate.getHandshakeHeaders();
091        }
092
093        @Override
094        public Map<String, Object> getAttributes() {
095                return this.delegate.getAttributes();
096        }
097
098        @Override
099        public Principal getPrincipal() {
100                return this.delegate.getPrincipal();
101        }
102
103        @Override
104        public InetSocketAddress getLocalAddress() {
105                return this.delegate.getLocalAddress();
106        }
107
108        @Override
109        public InetSocketAddress getRemoteAddress() {
110                return this.delegate.getRemoteAddress();
111        }
112
113        @Override
114        public String getAcceptedProtocol() {
115                return this.delegate.getAcceptedProtocol();
116        }
117
118        @Override
119        public List<WebSocketExtension> getExtensions() {
120                return this.delegate.getExtensions();
121        }
122
123        @Override
124        public void setTextMessageSizeLimit(int messageSizeLimit) {
125                this.delegate.setTextMessageSizeLimit(messageSizeLimit);
126        }
127
128        @Override
129        public int getTextMessageSizeLimit() {
130                return this.delegate.getTextMessageSizeLimit();
131        }
132
133        @Override
134        public void setBinaryMessageSizeLimit(int messageSizeLimit) {
135                this.delegate.setBinaryMessageSizeLimit(messageSizeLimit);
136        }
137
138        @Override
139        public int getBinaryMessageSizeLimit() {
140                return this.delegate.getBinaryMessageSizeLimit();
141        }
142
143        @Override
144        public boolean isOpen() {
145                return this.delegate.isOpen();
146        }
147
148        @Override
149        public void sendMessage(WebSocketMessage<?> message) throws IOException {
150                this.delegate.sendMessage(message);
151        }
152
153        @Override
154        public void close() throws IOException {
155                this.delegate.close();
156        }
157
158        @Override
159        public void close(CloseStatus status) throws IOException {
160                this.delegate.close(status);
161        }
162
163        @Override
164        public String toString() {
165                return getClass().getSimpleName() + " [delegate=" + this.delegate + "]";
166        }
167
168}