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.sockjs.transport.handler;
018
019import java.util.Arrays;
020import java.util.Collection;
021import java.util.LinkedHashSet;
022import java.util.Set;
023
024import javax.servlet.ServletContext;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028
029import org.springframework.scheduling.TaskScheduler;
030import org.springframework.web.context.ServletContextAware;
031import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
032import org.springframework.web.socket.sockjs.transport.TransportHandler;
033import org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService;
034
035/**
036 * A default implementation of {@link org.springframework.web.socket.sockjs.SockJsService}
037 * with all default {@link TransportHandler} implementations pre-registered.
038 *
039 * @author Rossen Stoyanchev
040 * @author Juergen Hoeller
041 * @since 4.0
042 */
043public class DefaultSockJsService extends TransportHandlingSockJsService implements ServletContextAware {
044
045        /**
046         * Create a DefaultSockJsService with default {@link TransportHandler handler} types.
047         * @param scheduler a task scheduler for heart-beat messages and removing
048         * timed-out sessions; the provided TaskScheduler should be declared as a
049         * Spring bean to ensure it is initialized at start up and shut down when the
050         * application stops.
051         */
052        public DefaultSockJsService(TaskScheduler scheduler) {
053                this(scheduler, getDefaultTransportHandlers(null));
054        }
055
056        /**
057         * Create a DefaultSockJsService with overridden {@link TransportHandler handler} types
058         * replacing the corresponding default handler implementation.
059         * @param scheduler a task scheduler for heart-beat messages and removing timed-out sessions;
060         * the provided TaskScheduler should be declared as a Spring bean to ensure it gets
061         * initialized at start-up and shuts down when the application stops
062         * @param handlerOverrides zero or more overrides to the default transport handler types
063         */
064        public DefaultSockJsService(TaskScheduler scheduler, TransportHandler... handlerOverrides) {
065                this(scheduler, Arrays.asList(handlerOverrides));
066        }
067
068        /**
069         * Create a DefaultSockJsService with overridden {@link TransportHandler handler} types
070         * replacing the corresponding default handler implementation.
071         * @param scheduler a task scheduler for heart-beat messages and removing timed-out sessions;
072         * the provided TaskScheduler should be declared as a Spring bean to ensure it gets
073         * initialized at start-up and shuts down when the application stops
074         * @param handlerOverrides zero or more overrides to the default transport handler types
075         */
076        public DefaultSockJsService(TaskScheduler scheduler, Collection<TransportHandler> handlerOverrides) {
077                super(scheduler, getDefaultTransportHandlers(handlerOverrides));
078        }
079
080
081        @SuppressWarnings("deprecation")
082        private static Set<TransportHandler> getDefaultTransportHandlers(Collection<TransportHandler> overrides) {
083                Set<TransportHandler> result = new LinkedHashSet<TransportHandler>(8);
084                result.add(new XhrPollingTransportHandler());
085                result.add(new XhrReceivingTransportHandler());
086                result.add(new XhrStreamingTransportHandler());
087                result.add(new JsonpPollingTransportHandler());
088                result.add(new JsonpReceivingTransportHandler());
089                result.add(new EventSourceTransportHandler());
090                result.add(new HtmlFileTransportHandler());
091                try {
092                        result.add(new WebSocketTransportHandler(new DefaultHandshakeHandler()));
093                }
094                catch (Exception ex) {
095                        Log logger = LogFactory.getLog(DefaultSockJsService.class);
096                        if (logger.isWarnEnabled()) {
097                                logger.warn("Failed to create a default WebSocketTransportHandler", ex);
098                        }
099                }
100                if (overrides != null) {
101                        result.addAll(overrides);
102                }
103                return result;
104        }
105
106        @Override
107        public void setServletContext(ServletContext servletContext) {
108                for (TransportHandler handler : getTransportHandlers().values()) {
109                        if (handler instanceof ServletContextAware) {
110                                ((ServletContextAware) handler).setServletContext(servletContext);
111                        }
112                }
113        }
114}