001/*
002 * Copyright 2002-2017 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.server.standard;
018
019import javax.servlet.ServletContext;
020import javax.websocket.WebSocketContainer;
021import javax.websocket.server.ServerContainer;
022
023import org.springframework.beans.factory.FactoryBean;
024import org.springframework.beans.factory.InitializingBean;
025import org.springframework.util.Assert;
026import org.springframework.web.context.ServletContextAware;
027
028/**
029 * A {@link FactoryBean} for configuring {@link javax.websocket.server.ServerContainer}.
030 * Since there is usually only one {@code ServerContainer} instance accessible under a
031 * well-known {@code javax.servlet.ServletContext} attribute, simply declaring this
032 * FactoryBean and using its setters allows for configuring the {@code ServerContainer}
033 * through Spring configuration.
034 *
035 * <p>This is useful even if the {@code ServerContainer} is not injected into any other
036 * bean within the Spring application context. For example, an application can configure
037 * a {@link org.springframework.web.socket.server.support.DefaultHandshakeHandler},
038 * a {@link org.springframework.web.socket.sockjs.SockJsService}, or
039 * {@link ServerEndpointExporter}, and separately declare this FactoryBean in order
040 * to customize the properties of the (one and only) {@code ServerContainer} instance.
041 *
042 * @author Rossen Stoyanchev
043 * @author Sam Brannen
044 * @since 4.0
045 */
046public class ServletServerContainerFactoryBean
047                implements FactoryBean<WebSocketContainer>, ServletContextAware, InitializingBean {
048
049        private Long asyncSendTimeout;
050
051        private Long maxSessionIdleTimeout;
052
053        private Integer maxTextMessageBufferSize;
054
055        private Integer maxBinaryMessageBufferSize;
056
057        private ServletContext servletContext;
058
059        private ServerContainer serverContainer;
060
061
062        public void setAsyncSendTimeout(long timeoutInMillis) {
063                this.asyncSendTimeout = timeoutInMillis;
064        }
065
066        public Long getAsyncSendTimeout() {
067                return this.asyncSendTimeout;
068        }
069
070        public void setMaxSessionIdleTimeout(long timeoutInMillis) {
071                this.maxSessionIdleTimeout = timeoutInMillis;
072        }
073
074        public Long getMaxSessionIdleTimeout() {
075                return this.maxSessionIdleTimeout;
076        }
077
078        public void setMaxTextMessageBufferSize(int bufferSize) {
079                this.maxTextMessageBufferSize = bufferSize;
080        }
081
082        public Integer getMaxTextMessageBufferSize() {
083                return this.maxTextMessageBufferSize;
084        }
085
086        public void setMaxBinaryMessageBufferSize(int bufferSize) {
087                this.maxBinaryMessageBufferSize = bufferSize;
088        }
089
090        public Integer getMaxBinaryMessageBufferSize() {
091                return this.maxBinaryMessageBufferSize;
092        }
093
094        @Override
095        public void setServletContext(ServletContext servletContext) {
096                this.servletContext = servletContext;
097        }
098
099
100        @Override
101        public void afterPropertiesSet() {
102                Assert.state(this.servletContext != null,
103                                "A ServletContext is required to access the javax.websocket.server.ServerContainer instance");
104                this.serverContainer = (ServerContainer) this.servletContext.getAttribute(
105                                "javax.websocket.server.ServerContainer");
106                Assert.state(this.serverContainer != null,
107                                "Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext");
108
109                if (this.asyncSendTimeout != null) {
110                        this.serverContainer.setAsyncSendTimeout(this.asyncSendTimeout);
111                }
112                if (this.maxSessionIdleTimeout != null) {
113                        this.serverContainer.setDefaultMaxSessionIdleTimeout(this.maxSessionIdleTimeout);
114                }
115                if (this.maxTextMessageBufferSize != null) {
116                        this.serverContainer.setDefaultMaxTextMessageBufferSize(this.maxTextMessageBufferSize);
117                }
118                if (this.maxBinaryMessageBufferSize != null) {
119                        this.serverContainer.setDefaultMaxBinaryMessageBufferSize(this.maxBinaryMessageBufferSize);
120                }
121        }
122
123
124        @Override
125        public ServerContainer getObject() {
126                return this.serverContainer;
127        }
128
129        @Override
130        public Class<?> getObjectType() {
131                return (this.serverContainer != null ? this.serverContainer.getClass() : ServerContainer.class);
132        }
133
134        @Override
135        public boolean isSingleton() {
136                return true;
137        }
138
139}