/* * Copyright 2002-2014 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.integration.config.xml; import org.w3c.dom.Element; import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.channel.FixedSubscriberChannel; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; /** * Base class for channel parsers. * * @author Mark Fisher * @author Dave Syer * @author Artem Bilan */ public abstract class AbstractChannelParser extends AbstractBeanDefinitionParser { @SuppressWarnings("rawtypes") @Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = this.buildBeanDefinition(element, parserContext); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); Element interceptorsElement = DomUtils.getChildElementByTagName(element, "interceptors"); String datatypeAttr = element.getAttribute("datatype"); String messageConverter = element.getAttribute("message-converter"); if (!FixedSubscriberChannel.class.getName().equals(builder.getBeanDefinition().getBeanClassName())) { ManagedList interceptors = null; if (interceptorsElement != null) { ChannelInterceptorParser interceptorParser = new ChannelInterceptorParser(); interceptors = interceptorParser.parseInterceptors(interceptorsElement, parserContext); } if (interceptors == null) { interceptors = new ManagedList(); } if (StringUtils.hasText(datatypeAttr)) { builder.addPropertyValue("datatypes", datatypeAttr); } if (StringUtils.hasText(messageConverter)) { builder.addPropertyReference("messageConverter", messageConverter); } builder.addPropertyValue("interceptors", interceptors); String scopeAttr = element.getAttribute("scope"); if (StringUtils.hasText(scopeAttr)) { builder.setScope(scopeAttr); } } else { if (interceptorsElement != null) { parserContext.getReaderContext().error("Cannot have interceptors when 'fixed-subscriber=\"true\"'", element); } if (StringUtils.hasText(datatypeAttr)) { parserContext.getReaderContext().error("Cannot have 'datatype' when 'fixed-subscriber=\"true\"'", element); } if (StringUtils.hasText(messageConverter)) { parserContext.getReaderContext().error("Cannot have 'message-converter' when 'fixed-subscriber=\"true\"'", element); } } beanDefinition.setSource(parserContext.extractSource(element)); return beanDefinition; } @Override protected void registerBeanDefinition(BeanDefinitionHolder definition, BeanDefinitionRegistry registry) { String scope = definition.getBeanDefinition().getScope(); if (!AbstractBeanDefinition.SCOPE_DEFAULT.equals(scope) && !AbstractBeanDefinition.SCOPE_SINGLETON.equals(scope) && !AbstractBeanDefinition.SCOPE_PROTOTYPE.equals(scope)) { definition = ScopedProxyUtils.createScopedProxy(definition, registry, false); } super.registerBeanDefinition(definition, registry); } /** * Subclasses must implement this method to create the bean definition. * The class must be defined, and any implementation-specific constructor * arguments or properties should be configured. This base class will * configure the interceptors including the 'datatype' interceptor if * the 'datatype' attribute is defined on the channel element. * * @param element The element. * @param parserContext The parser context. * @return The bean definition builder. */ protected abstract BeanDefinitionBuilder buildBeanDefinition(Element element, ParserContext parserContext); }