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