Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.socket.config;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Element;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
import org.springframework.messaging.converter.ByteArrayMessageConverter;
import org.springframework.messaging.converter.CompositeMessageConverter;
import org.springframework.messaging.converter.DefaultContentTypeResolver;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.SimpSessionScope;
import org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler;
import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler;
import org.springframework.messaging.simp.user.DefaultUserDestinationResolver;
import org.springframework.messaging.simp.user.MultiServerUserRegistry;
import org.springframework.messaging.simp.user.UserDestinationMessageHandler;
import org.springframework.messaging.simp.user.UserRegistryMessageHandler;
import org.springframework.messaging.support.ExecutorSubscribableChannel;
import org.springframework.messaging.support.ImmutableMessageChannelInterceptor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
import org.springframework.web.socket.messaging.DefaultSimpUserRegistry;
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
import org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessageHandler;
import org.springframework.web.socket.server.support.OriginHandshakeInterceptor;
import org.springframework.web.socket.server.support.WebSocketHandlerMapping;
import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;
import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;
/**
* A {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that provides
* the configuration for the {@code } XML namespace element.
*
*
Registers a Spring MVC {@link org.springframework.web.servlet.HandlerMapping}
* with order 1 to map HTTP WebSocket handshake requests from STOMP/WebSocket clients.
*
*
Registers the following {@link org.springframework.messaging.MessageChannel}s:
*
*
"clientInboundChannel" for receiving messages from clients (e.g. WebSocket clients)
*
"clientOutboundChannel" for sending messages to clients (e.g. WebSocket clients)
*
"brokerChannel" for sending messages from within the application to the message broker
*
*
*
Registers one of the following based on the selected message broker options:
*
*
a {@link SimpleBrokerMessageHandler} if the is used
*
a {@link StompBrokerRelayMessageHandler} if the is used
*
*
*
Registers a {@link UserDestinationMessageHandler} for handling user destinations.
*
* @author Brian Clozel
* @author Rossen Stoyanchev
* @since 4.0
*/
class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
public static final String WEB_SOCKET_HANDLER_BEAN_NAME = "subProtocolWebSocketHandler";
public static final String SCHEDULER_BEAN_NAME = "messageBrokerScheduler";
public static final String SOCKJS_SCHEDULER_BEAN_NAME = "messageBrokerSockJsScheduler";
private static final int DEFAULT_MAPPING_ORDER = 1;
private static final boolean jackson2Present = ClassUtils.isPresent(
"com.fasterxml.jackson.databind.ObjectMapper", MessageBrokerBeanDefinitionParser.class.getClassLoader());
@Override
public BeanDefinition parse(Element element, ParserContext context) {
Object source = context.extractSource(element);
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
context.pushContainingComponent(compDefinition);
Element channelElem = DomUtils.getChildElementByTagName(element, "client-inbound-channel");
RuntimeBeanReference inChannel = getMessageChannel("clientInboundChannel", channelElem, context, source);
channelElem = DomUtils.getChildElementByTagName(element, "client-outbound-channel");
RuntimeBeanReference outChannel = getMessageChannel("clientOutboundChannel", channelElem, context, source);
channelElem = DomUtils.getChildElementByTagName(element, "broker-channel");
RuntimeBeanReference brokerChannel = getMessageChannel("brokerChannel", channelElem, context, source);
RuntimeBeanReference userRegistry = registerUserRegistry(element, context, source);
Object userDestHandler = registerUserDestHandler(element, userRegistry, inChannel, brokerChannel, context, source);
RuntimeBeanReference converter = registerMessageConverter(element, context, source);
RuntimeBeanReference template = registerMessagingTemplate(element, brokerChannel, converter, context, source);
registerAnnotationMethodMessageHandler(element, inChannel, outChannel,converter, template, context, source);
RootBeanDefinition broker = registerMessageBroker(element, inChannel, outChannel, brokerChannel,
userDestHandler, template, userRegistry, context, source);
// WebSocket and sub-protocol handling
ManagedMap urlMap = registerHandlerMapping(element, context, source);
RuntimeBeanReference stompHandler = registerStompHandler(element, inChannel, outChannel, context, source);
for (Element endpointElem : DomUtils.getChildElementsByTagName(element, "stomp-endpoint")) {
RuntimeBeanReference requestHandler = registerRequestHandler(endpointElem, stompHandler, context, source);
String pathAttribute = endpointElem.getAttribute("path");
Assert.state(StringUtils.hasText(pathAttribute), "Invalid (no path mapping)");
List paths = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ","));
for (String path : paths) {
path = path.trim();
Assert.state(StringUtils.hasText(path), "Invalid path attribute: " + pathAttribute);
if (DomUtils.getChildElementByTagName(endpointElem, "sockjs") != null) {
path = path.endsWith("/") ? path + "**" : path + "/**";
}
urlMap.put(path, requestHandler);
}
}
Map scopeMap = Collections.singletonMap("websocket", new SimpSessionScope());
RootBeanDefinition scopeConfigurer = new RootBeanDefinition(CustomScopeConfigurer.class);
scopeConfigurer.getPropertyValues().add("scopes", scopeMap);
registerBeanDefByName("webSocketScopeConfigurer", scopeConfigurer, context, source);
registerWebSocketMessageBrokerStats(broker, inChannel, outChannel, context, source);
context.popAndRegisterContainingComponent();
return null;
}
private RuntimeBeanReference registerUserRegistry(Element element, ParserContext context, Object source) {
Element relayElement = DomUtils.getChildElementByTagName(element, "stomp-broker-relay");
boolean multiServer = (relayElement != null && relayElement.hasAttribute("user-registry-broadcast"));
if (multiServer) {
RootBeanDefinition localRegistryBeanDef = new RootBeanDefinition(DefaultSimpUserRegistry.class);
RootBeanDefinition beanDef = new RootBeanDefinition(MultiServerUserRegistry.class);
beanDef.getConstructorArgumentValues().addIndexedArgumentValue(0, localRegistryBeanDef);
String beanName = registerBeanDef(beanDef, context, source);
return new RuntimeBeanReference(beanName);
}
else {
RootBeanDefinition beanDef = new RootBeanDefinition(DefaultSimpUserRegistry.class);
String beanName = registerBeanDef(beanDef, context, source);
return new RuntimeBeanReference(beanName);
}
}
private ManagedMap registerHandlerMapping(Element element,
ParserContext context, Object source) {
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(WebSocketHandlerMapping.class);
String orderAttribute = element.getAttribute("order");
int order = orderAttribute.isEmpty() ? DEFAULT_MAPPING_ORDER : Integer.valueOf(orderAttribute);
handlerMappingDef.getPropertyValues().add("order", order);
String pathHelper = element.getAttribute("path-helper");
if (StringUtils.hasText(pathHelper)) {
handlerMappingDef.getPropertyValues().add("urlPathHelper", new RuntimeBeanReference(pathHelper));
}
ManagedMap urlMap = new ManagedMap();
urlMap.setSource(source);
handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
registerBeanDef(handlerMappingDef, context, source);
return urlMap;
}
private RuntimeBeanReference getMessageChannel(String name, Element element, ParserContext context, Object source) {
RootBeanDefinition executor;
if (element == null) {
executor = getDefaultExecutorBeanDefinition(name);
}
else {
Element executorElem = DomUtils.getChildElementByTagName(element, "executor");
if (executorElem == null) {
executor = getDefaultExecutorBeanDefinition(name);
}
else {
executor = new RootBeanDefinition(ThreadPoolTaskExecutor.class);
if (executorElem.hasAttribute("core-pool-size")) {
executor.getPropertyValues().add("corePoolSize", executorElem.getAttribute("core-pool-size"));
}
if (executorElem.hasAttribute("max-pool-size")) {
executor.getPropertyValues().add("maxPoolSize", executorElem.getAttribute("max-pool-size"));
}
if (executorElem.hasAttribute("keep-alive-seconds")) {
executor.getPropertyValues().add("keepAliveSeconds", executorElem.getAttribute("keep-alive-seconds"));
}
if (executorElem.hasAttribute("queue-capacity")) {
executor.getPropertyValues().add("queueCapacity", executorElem.getAttribute("queue-capacity"));
}
}
}
ConstructorArgumentValues argValues = new ConstructorArgumentValues();
if (executor != null) {
executor.getPropertyValues().add("threadNamePrefix", name + "-");
String executorName = name + "Executor";
registerBeanDefByName(executorName, executor, context, source);
argValues.addIndexedArgumentValue(0, new RuntimeBeanReference(executorName));
}
RootBeanDefinition channelDef = new RootBeanDefinition(ExecutorSubscribableChannel.class, argValues, null);
ManagedList interceptors = new ManagedList