diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractMessageChannel.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractMessageChannel.java index 560fa34b28..40a93834be 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractMessageChannel.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractMessageChannel.java @@ -415,7 +415,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport * false if the message cannot be sent within the allotted * time or the sending thread is interrupted. */ - @Override + @Override // NOSONAR complexity public boolean send(Message messageArg, long timeout) { Assert.notNull(messageArg, "message must not be null"); Assert.notNull(messageArg.getPayload(), "message payload must not be null"); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractPollableChannel.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractPollableChannel.java index 0f6f0b9e9e..051165592e 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractPollableChannel.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractPollableChannel.java @@ -87,7 +87,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel * is available within the allotted time or the receiving thread is * interrupted. */ - @Override + @Override // NOSONAR complexity @Nullable public Message receive(long timeout) { ChannelInterceptorList interceptorList = getIChannelInterceptorList(); @@ -119,7 +119,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel counted = true; } - if (traceEnabled) { + if (logger.isDebugEnabled()) { logger.debug("postReceive on channel '" + this + "', message: " + message); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java index 852ed96003..a4ba3d0db7 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractConsumerEndpointParser.java @@ -97,7 +97,8 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit ManagedList adviceChain = IntegrationNamespaceUtils.configureAdviceChain(adviceChainElement, txElement, true, handlerBuilder.getRawBeanDefinition(), parserContext); - if (!CollectionUtils.isEmpty(adviceChain)) { + boolean hasAdviceChain = !CollectionUtils.isEmpty(adviceChain); + if (hasAdviceChain) { handlerBuilder.addPropertyValue("adviceChain", adviceChain); } @@ -111,12 +112,11 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit + "' attribute isn't allowed for a nested (e.g. inside a ) endpoint element: " + elementDescription + ".", element); } - if (!replyChannelInChainAllowed(element)) { - if (StringUtils.hasText(element.getAttribute("reply-channel"))) { - parserContext.getReaderContext().error("The 'reply-channel' attribute isn't" - + " allowed for a nested (e.g. inside a ) outbound gateway element: " - + elementDescription + ".", element); - } + if (!replyChannelInChainAllowed(element) + && StringUtils.hasText(element.getAttribute("reply-channel"))) { + parserContext.getReaderContext().error("The 'reply-channel' attribute isn't" + + " allowed for a nested (e.g. inside a ) outbound gateway element: " + + elementDescription + ".", element); } return handlerBeanDefinition; } @@ -131,7 +131,7 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerEndpointFactoryBean.class); - if (!CollectionUtils.isEmpty(adviceChain)) { + if (hasAdviceChain) { builder.addPropertyValue("adviceChain", adviceChain); } @@ -151,13 +151,7 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit builder.addPropertyValue("inputChannelName", inputChannelName); List pollerElementList = DomUtils.getChildElementsByTagName(element, "poller"); - if (!CollectionUtils.isEmpty(pollerElementList)) { - if (pollerElementList.size() != 1) { - parserContext.getReaderContext().error( - "at most one poller element may be configured for an endpoint", element); - } - IntegrationNamespaceUtils.configurePollerMetadata(pollerElementList.get(0), builder, parserContext); - } + poller(element, parserContext, builder, pollerElementList); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.AUTO_STARTUP); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.PHASE); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.ROLE); @@ -168,6 +162,17 @@ public abstract class AbstractConsumerEndpointParser extends AbstractBeanDefinit return null; } + private void poller(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, + List pollerElementList) { + if (!CollectionUtils.isEmpty(pollerElementList)) { + if (pollerElementList.size() != 1) { + parserContext.getReaderContext().error( + "at most one poller element may be configured for an endpoint", element); + } + IntegrationNamespaceUtils.configurePollerMetadata(pollerElementList.get(0), builder, parserContext); + } + } + private void registerChannelForCreation(ParserContext parserContext, String inputChannelName) { if (parserContext.getRegistry() .containsBeanDefinition(IntegrationContextUtils.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME)) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractDelegatingConsumerEndpointParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractDelegatingConsumerEndpointParser.java index b60f579b7c..b94a16fdec 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractDelegatingConsumerEndpointParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractDelegatingConsumerEndpointParser.java @@ -42,7 +42,8 @@ abstract class AbstractDelegatingConsumerEndpointParser extends AbstractConsumer protected final BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { Object source = parserContext.extractSource(element); BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getFactoryBeanClassName()); - BeanComponentDefinition innerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext); + BeanComponentDefinition innerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, + parserContext); String ref = element.getAttribute(REF_ATTRIBUTE); String expression = element.getAttribute(EXPRESSION_ATTRIBUTE); boolean hasRef = StringUtils.hasText(ref); @@ -50,38 +51,15 @@ abstract class AbstractDelegatingConsumerEndpointParser extends AbstractConsumer Element scriptElement = DomUtils.getChildElementByTagName(element, "script"); Element expressionElement = DomUtils.getChildElementByTagName(element, "expression"); if (innerDefinition != null) { - if (hasRef || hasExpression || expressionElement != null) { - parserContext.getReaderContext().error( - "Neither 'ref' nor 'expression' are permitted when an inner bean () is configured on element " + - IntegrationNamespaceUtils.createElementDescription(element) + ".", source); - return null; - } - builder.addPropertyValue("targetObject", innerDefinition); + innerDefinition(element, parserContext, source, builder, innerDefinition, hasRef, hasExpression, + expressionElement); } else if (scriptElement != null) { - if (hasRef || hasExpression || expressionElement != null) { - parserContext.getReaderContext().error( - "Neither 'ref' nor 'expression' are permitted when an inner script element is configured on element " + - IntegrationNamespaceUtils.createElementDescription(element) + ".", source); - return null; - } - BeanDefinition scriptBeanDefinition = parserContext.getDelegate().parseCustomElement(scriptElement, builder.getBeanDefinition()); - builder.addPropertyValue("targetObject", scriptBeanDefinition); + scriptElement(element, parserContext, source, builder, hasRef, hasExpression, scriptElement, + expressionElement); } else if (expressionElement != null) { - if (hasRef || hasExpression) { - parserContext.getReaderContext().error( - "Neither 'ref' nor 'expression' are permitted when an inner 'expression' element is configured on element " + - IntegrationNamespaceUtils.createElementDescription(element) + ".", source); - return null; - } - BeanDefinitionBuilder dynamicExpressionBuilder = BeanDefinitionBuilder.genericBeanDefinition( - DynamicExpression.class); - String key = expressionElement.getAttribute("key"); - String expressionSourceReference = expressionElement.getAttribute("source"); - dynamicExpressionBuilder.addConstructorArgValue(key); - dynamicExpressionBuilder.addConstructorArgReference(expressionSourceReference); - builder.addPropertyValue("expression", dynamicExpressionBuilder.getBeanDefinition()); + expressionElement(element, parserContext, source, builder, hasRef, hasExpression, expressionElement); } else if (hasRef && hasExpression) { parserContext.getReaderContext().error( @@ -109,6 +87,45 @@ abstract class AbstractDelegatingConsumerEndpointParser extends AbstractConsumer return builder; } + private void innerDefinition(Element element, ParserContext parserContext, Object source, + BeanDefinitionBuilder builder, BeanComponentDefinition innerDefinition, boolean hasRef, + boolean hasExpression, Element expressionElement) { + if (hasRef || hasExpression || expressionElement != null) { + parserContext.getReaderContext().error( + "Neither 'ref' nor 'expression' are permitted when an inner bean () is configured on element " + + IntegrationNamespaceUtils.createElementDescription(element) + ".", source); + } + builder.addPropertyValue("targetObject", innerDefinition); + } + + private void scriptElement(Element element, ParserContext parserContext, Object source, + BeanDefinitionBuilder builder, boolean hasRef, boolean hasExpression, Element scriptElement, + Element expressionElement) { + if (hasRef || hasExpression || expressionElement != null) { + parserContext.getReaderContext().error( + "Neither 'ref' nor 'expression' are permitted when an inner script element is configured on element " + + IntegrationNamespaceUtils.createElementDescription(element) + ".", source); + } + BeanDefinition scriptBeanDefinition = parserContext.getDelegate().parseCustomElement(scriptElement, builder.getBeanDefinition()); + builder.addPropertyValue("targetObject", scriptBeanDefinition); + } + + private void expressionElement(Element element, ParserContext parserContext, Object source, + BeanDefinitionBuilder builder, boolean hasRef, boolean hasExpression, Element expressionElement) { + if (hasRef || hasExpression) { + parserContext.getReaderContext().error( + "Neither 'ref' nor 'expression' are permitted when an inner 'expression' element is configured on element " + + IntegrationNamespaceUtils.createElementDescription(element) + ".", source); + } + BeanDefinitionBuilder dynamicExpressionBuilder = BeanDefinitionBuilder.genericBeanDefinition( + DynamicExpression.class); + String key = expressionElement.getAttribute("key"); + String expressionSourceReference = expressionElement.getAttribute("source"); + dynamicExpressionBuilder.addConstructorArgValue(key); + dynamicExpressionBuilder.addConstructorArgReference(expressionSourceReference); + builder.addPropertyValue("expression", dynamicExpressionBuilder.getBeanDefinition()); + } + private void methodAttribute(Element element, ParserContext parserContext, Object source, BeanDefinitionBuilder builder, BeanComponentDefinition innerDefinition, boolean hasRef, boolean hasExpression, Element expressionElement) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java index 75538282cc..860ca71b48 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java @@ -46,7 +46,7 @@ import org.springframework.util.xml.DomUtils; */ public class DefaultInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser { - @Override + @Override // NOSONAR complexity protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) { Object source = parserContext.extractSource(element); BeanMetadataElement result = null; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java index 2e6d557972..61b3ec303c 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/EnricherParser.java @@ -59,6 +59,26 @@ public class EnricherParser extends AbstractConsumerEndpointParser { IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply"); + propertySubElements(element, parserContext, builder); + + headerSubElements(element, parserContext, builder); + + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "should-clone-payload"); + + String requestPayloadExpression = element.getAttribute("request-payload-expression"); + + if (StringUtils.hasText(requestPayloadExpression)) { + BeanDefinitionBuilder expressionBuilder = + BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class) + .addConstructorArgValue(requestPayloadExpression); + builder.addPropertyValue("requestPayloadExpression", expressionBuilder.getBeanDefinition()); + } + + return builder; + } + + private void propertySubElements(Element element, ParserContext parserContext, + final BeanDefinitionBuilder builder) { List subElements = DomUtils.getChildElementsByTagName(element, "property"); if (!CollectionUtils.isEmpty(subElements)) { ManagedMap expressions = new ManagedMap(); @@ -83,39 +103,9 @@ public class EnricherParser extends AbstractConsumerEndpointParser { .error("One of 'value' or 'expression' or 'null-result-expression' is required", element); } - BeanDefinition expressionDef = null; - BeanDefinition nullResultExpressionExpressionDef; - - if (hasAttributeValue) { - BeanDefinitionBuilder expressionBuilder = - BeanDefinitionBuilder.genericBeanDefinition(ValueExpression.class); - if (StringUtils.hasText(type)) { - expressionBuilder.addConstructorArgValue(new TypedStringValue(value, type)); - } - else { - expressionBuilder.addConstructorArgValue(value); - } - expressionDef = expressionBuilder.getBeanDefinition(); - } - else if (hasAttributeExpression) { - if (StringUtils.hasText(type)) { - parserContext.getReaderContext().error("The 'type' attribute for '' of '' " + - "is not allowed with an 'expression' attribute.", element); - } - expressionDef = BeanDefinitionBuilder - .genericBeanDefinition(ExpressionFactoryBean.class) - .addConstructorArgValue(expression) - .getBeanDefinition(); - } - if (expressionDef != null) { - expressions.put(name, expressionDef); - } - if (hasAttributeNullResultExpression) { - nullResultExpressionExpressionDef = - BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class) - .addConstructorArgValue(nullResultExpression).getBeanDefinition(); - nullResultExpressions.put(name, nullResultExpressionExpressionDef); - } + expression(element, parserContext, expressions, nullResultExpressions, name, value, type, expression, + nullResultExpression, hasAttributeValue, hasAttributeExpression, + hasAttributeNullResultExpression); } if (expressions.size() > 0) { builder.addPropertyValue("propertyExpressions", expressions); @@ -124,7 +114,50 @@ public class EnricherParser extends AbstractConsumerEndpointParser { builder.addPropertyValue("nullResultPropertyExpressions", nullResultExpressions); } } + } + private void expression(Element element, ParserContext parserContext, ManagedMap expressions, + ManagedMap nullResultExpressions, String name, String value, String type, String expression, + String nullResultExpression, boolean hasAttributeValue, boolean hasAttributeExpression, + boolean hasAttributeNullResultExpression) { + + BeanDefinition expressionDef = null; + BeanDefinition nullResultExpressionExpressionDef; + + if (hasAttributeValue) { + BeanDefinitionBuilder expressionBuilder = + BeanDefinitionBuilder.genericBeanDefinition(ValueExpression.class); + if (StringUtils.hasText(type)) { + expressionBuilder.addConstructorArgValue(new TypedStringValue(value, type)); + } + else { + expressionBuilder.addConstructorArgValue(value); + } + expressionDef = expressionBuilder.getBeanDefinition(); + } + else if (hasAttributeExpression) { + if (StringUtils.hasText(type)) { + parserContext.getReaderContext().error("The 'type' attribute for '' of '' " + + "is not allowed with an 'expression' attribute.", element); + } + expressionDef = BeanDefinitionBuilder + .genericBeanDefinition(ExpressionFactoryBean.class) + .addConstructorArgValue(expression) + .getBeanDefinition(); + } + if (expressionDef != null) { + expressions.put(name, expressionDef); + } + if (hasAttributeNullResultExpression) { + nullResultExpressionExpressionDef = + BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class) + .addConstructorArgValue(nullResultExpression).getBeanDefinition(); + nullResultExpressions.put(name, nullResultExpressionExpressionDef); + } + } + + private void headerSubElements(Element element, ParserContext parserContext, final BeanDefinitionBuilder builder) { + List subElements; subElements = DomUtils.getChildElementsByTagName(element, "header"); if (!CollectionUtils.isEmpty(subElements)) { ManagedMap expressions = new ManagedMap(); @@ -144,45 +177,11 @@ public class EnricherParser extends AbstractConsumerEndpointParser { if (!hasAttributeValue && !hasAttributeExpression && !hasAttributeNullResultExpression) { parserContext.getReaderContext() - .error("One of 'value' or 'expression' or 'null-result-expression' is required", subElement); - } - BeanDefinition expressionDef = null; - if (hasAttributeValue) { - expressionDef = new RootBeanDefinition(LiteralExpression.class); - expressionDef.getConstructorArgumentValues().addGenericArgumentValue(valueElementValue); - } - else if (hasAttributeExpression) { - expressionDef = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined(EXPRESSION_ATTRIBUTE, + .error("One of 'value' or 'expression' or 'null-result-expression' is required", subElement); } - - if (StringUtils.hasText(subElement.getAttribute(EXPRESSION_ATTRIBUTE)) - && StringUtils.hasText(subElement.getAttribute(TYPE_ATTRIBUTE))) { - parserContext.getReaderContext() - .warning("The use of a 'type' attribute is deprecated since 4.0 " - + "when using 'expression'", subElement); - } - if (expressionDef != null) { - BeanDefinitionBuilder valueProcessorBuilder = BeanDefinitionBuilder - .genericBeanDefinition(ExpressionEvaluatingHeaderValueMessageProcessor.class) - .addConstructorArgValue(expressionDef) - .addConstructorArgValue(subElement.getAttribute(TYPE_ATTRIBUTE)); - IntegrationNamespaceUtils.setValueIfAttributeDefined(valueProcessorBuilder, subElement, - "overwrite"); - expressions.put(name, valueProcessorBuilder.getBeanDefinition()); - } - if (hasAttributeNullResultExpression) { - BeanDefinition nullResultExpressionDefinition = IntegrationNamespaceUtils - .createExpressionDefIfAttributeDefined("null-result-expression", subElement); - BeanDefinitionBuilder nullResultValueProcessorBuilder = BeanDefinitionBuilder - .genericBeanDefinition(ExpressionEvaluatingHeaderValueMessageProcessor.class) - .addConstructorArgValue(nullResultExpressionDefinition) - .addConstructorArgValue(subElement.getAttribute(TYPE_ATTRIBUTE)); - IntegrationNamespaceUtils.setValueIfAttributeDefined(nullResultValueProcessorBuilder, subElement, - "overwrite"); - nullResultHeaderExpressions.put(name, nullResultValueProcessorBuilder.getBeanDefinition()); - } + headerExpression(parserContext, expressions, nullResultHeaderExpressions, subElement, name, + valueElementValue, hasAttributeValue, hasAttributeExpression, hasAttributeNullResultExpression); } if (expressions.size() > 0) { builder.addPropertyValue("headerExpressions", expressions); @@ -191,19 +190,50 @@ public class EnricherParser extends AbstractConsumerEndpointParser { builder.addPropertyValue("nullResultHeaderExpressions", nullResultHeaderExpressions); } } + } - IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "should-clone-payload"); + private void headerExpression(ParserContext parserContext, ManagedMap expressions, + ManagedMap nullResultHeaderExpressions, Element subElement, String name, + String valueElementValue, boolean hasAttributeValue, boolean hasAttributeExpression, + boolean hasAttributeNullResultExpression) { - String requestPayloadExpression = element.getAttribute("request-payload-expression"); - - if (StringUtils.hasText(requestPayloadExpression)) { - BeanDefinitionBuilder expressionBuilder = - BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class) - .addConstructorArgValue(requestPayloadExpression); - builder.addPropertyValue("requestPayloadExpression", expressionBuilder.getBeanDefinition()); + BeanDefinition expressionDef = null; + if (hasAttributeValue) { + expressionDef = new RootBeanDefinition(LiteralExpression.class); + expressionDef.getConstructorArgumentValues().addGenericArgumentValue(valueElementValue); + } + else if (hasAttributeExpression) { + expressionDef = + IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined(EXPRESSION_ATTRIBUTE, + subElement); } - return builder; + if (StringUtils.hasText(subElement.getAttribute(EXPRESSION_ATTRIBUTE)) + && StringUtils.hasText(subElement.getAttribute(TYPE_ATTRIBUTE))) { + parserContext.getReaderContext() + .warning("The use of a 'type' attribute is deprecated since 4.0 " + + "when using 'expression'", subElement); + } + if (expressionDef != null) { + BeanDefinitionBuilder valueProcessorBuilder = BeanDefinitionBuilder + .genericBeanDefinition(ExpressionEvaluatingHeaderValueMessageProcessor.class) + .addConstructorArgValue(expressionDef) + .addConstructorArgValue(subElement.getAttribute(TYPE_ATTRIBUTE)); + IntegrationNamespaceUtils.setValueIfAttributeDefined(valueProcessorBuilder, subElement, + "overwrite"); + expressions.put(name, valueProcessorBuilder.getBeanDefinition()); + } + if (hasAttributeNullResultExpression) { + BeanDefinition nullResultExpressionDefinition = IntegrationNamespaceUtils + .createExpressionDefIfAttributeDefined("null-result-expression", subElement); + BeanDefinitionBuilder nullResultValueProcessorBuilder = BeanDefinitionBuilder + .genericBeanDefinition(ExpressionEvaluatingHeaderValueMessageProcessor.class) + .addConstructorArgValue(nullResultExpressionDefinition) + .addConstructorArgValue(subElement.getAttribute(TYPE_ATTRIBUTE)); + IntegrationNamespaceUtils.setValueIfAttributeDefined(nullResultValueProcessorBuilder, subElement, + "overwrite"); + nullResultHeaderExpressions.put(name, nullResultValueProcessorBuilder.getBeanDefinition()); + } } @Override diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java index 73950101c8..097c73e347 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java @@ -51,7 +51,6 @@ public class GatewayParser implements BeanDefinitionParser { private final MessagingGatewayRegistrar registrar = new MessagingGatewayRegistrar(); @Override - @SuppressWarnings("rawtypes") public BeanDefinition parse(final Element element, ParserContext parserContext) { boolean isNested = parserContext.isNested(); @@ -80,6 +79,24 @@ public class GatewayParser implements BeanDefinitionParser { element.getAttribute(isNested ? "request-timeout" : "default-request-timeout")); + headers(element, gatewayAttributes); + + methods(element, parserContext, gatewayAttributes); + + gatewayAttributes.put("serviceInterface", element.getAttribute("service-interface")); + + BeanDefinitionHolder gatewayHolder = this.registrar.parse(gatewayAttributes); + if (isNested) { + return gatewayHolder.getBeanDefinition(); + } + else { + BeanDefinitionReaderUtils.registerBeanDefinition(gatewayHolder, parserContext.getRegistry()); + return null; + } + } + + @SuppressWarnings("rawtypes") + private void headers(final Element element, final Map gatewayAttributes) { List headerElements = DomUtils.getChildElementsByTagName(element, "default-header"); if (!CollectionUtils.isEmpty(headerElements)) { List> headers = new ArrayList>(headerElements.size()); @@ -93,7 +110,10 @@ public class GatewayParser implements BeanDefinitionParser { } gatewayAttributes.put("defaultHeaders", headers.toArray(new Map[0])); } + } + private void methods(final Element element, ParserContext parserContext, + final Map gatewayAttributes) { List methodElements = DomUtils.getChildElementsByTagName(element, "method"); if (!CollectionUtils.isEmpty(methodElements)) { Map methodMetadataMap = new ManagedMap(); @@ -134,17 +154,6 @@ public class GatewayParser implements BeanDefinitionParser { gatewayAttributes.put("methods", methodMetadataMap); } - - gatewayAttributes.put("serviceInterface", element.getAttribute("service-interface")); - - BeanDefinitionHolder gatewayHolder = this.registrar.parse(gatewayAttributes); - if (isNested) { - return gatewayHolder.getBeanDefinition(); - } - else { - BeanDefinitionReaderUtils.registerBeanDefinition(gatewayHolder, parserContext.getRegistry()); - return null; - } } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java index 6cfbd5b75d..6f41ac10a1 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java @@ -104,53 +104,59 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { - String headerName = null; - Element headerElement = (Element) node; - String elementName = node.getLocalName(); - String headerType = null; - String expression = null; - String overwrite = headerElement.getAttribute("overwrite"); - if ("header".equals(elementName)) { - headerName = headerElement.getAttribute(NAME_ATTRIBUTE); - } - else { - headerName = this.elementToNameMap.get(elementName); - headerType = this.elementToTypeMap.get(elementName); - if (headerType != null && StringUtils.hasText(headerElement.getAttribute(TYPE_ATTRIBUTE))) { - parserContext.getReaderContext().error("The " + elementName - + " header does not accept a 'type' attribute. The required type is [" - + headerType + "]", element); - } - } - if (headerType == null) { - headerType = headerElement.getAttribute(TYPE_ATTRIBUTE); - } - if (headerName == null) { - String ttlExpression = headerElement.getAttribute("time-to-live-expression"); - if (cannedHeaderElementExpressions.containsKey(elementName)) { - for (int j = 0; j < cannedHeaderElementExpressions.get(elementName).length; j++) { - headerName = cannedHeaderElementExpressions.get(elementName)[j][0]; - expression = cannedHeaderElementExpressions.get(elementName)[j][1]; - if (StringUtils.hasText(ttlExpression)) { - expression = expression.replace("####", ttlExpression); - } - else { - expression = expression.replace(", ####", ""); - } - overwrite = "true"; - addHeader(element, headers, parserContext, headerName, headerElement, headerType, - expression, overwrite); - } - } - } - else { - addHeader(element, headers, parserContext, headerName, headerElement, headerType, null, overwrite); - } + elementNode(element, headers, parserContext, node); } } } - private void addHeader(Element element, ManagedMap headers, ParserContext parserContext, + private void elementNode(Element element, ManagedMap headers, ParserContext parserContext, + Node node) { + + String headerName = null; + Element headerElement = (Element) node; + String elementName = node.getLocalName(); + String headerType = null; + String expression = null; + String overwrite = headerElement.getAttribute("overwrite"); + if ("header".equals(elementName)) { + headerName = headerElement.getAttribute(NAME_ATTRIBUTE); + } + else { + headerName = this.elementToNameMap.get(elementName); + headerType = this.elementToTypeMap.get(elementName); + if (headerType != null && StringUtils.hasText(headerElement.getAttribute(TYPE_ATTRIBUTE))) { + parserContext.getReaderContext().error("The " + elementName + + " header does not accept a 'type' attribute. The required type is [" + + headerType + "]", element); + } + } + if (headerType == null) { + headerType = headerElement.getAttribute(TYPE_ATTRIBUTE); + } + if (headerName == null) { + String ttlExpression = headerElement.getAttribute("time-to-live-expression"); + if (cannedHeaderElementExpressions.containsKey(elementName)) { + for (int j = 0; j < cannedHeaderElementExpressions.get(elementName).length; j++) { + headerName = cannedHeaderElementExpressions.get(elementName)[j][0]; + expression = cannedHeaderElementExpressions.get(elementName)[j][1]; + if (StringUtils.hasText(ttlExpression)) { + expression = expression.replace("####", ttlExpression); + } + else { + expression = expression.replace(", ####", ""); + } + overwrite = "true"; + addHeader(element, headers, parserContext, headerName, headerElement, headerType, + expression, overwrite); + } + } + } + else { + addHeader(element, headers, parserContext, headerName, headerElement, headerType, null, overwrite); + } + } + + private void addHeader(Element element, ManagedMap headers, ParserContext parserContext, // NOSONAR complexity String headerName, Element headerElement, String headerType, @Nullable String expressionArg, String overwrite) { @@ -206,6 +212,17 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar innerComponentDefinition = parserContext.getDelegate().parseCustomElement(scriptElement); } + BeanDefinitionBuilder valueProcessorBuilder = valueProcessor(element, parserContext, headerName, headerElement, + headerType, overwrite, value, ref, method, expression, expressionElement, isValue, isRef, hasMethod, + isExpression, isScript, innerComponentDefinition); + headers.put(headerName, valueProcessorBuilder.getBeanDefinition()); + } + + private BeanDefinitionBuilder valueProcessor(Element element, ParserContext parserContext, String headerName, + Element headerElement, String headerType, String overwrite, String value, String ref, String method, + String expression, Element expressionElement, boolean isValue, boolean isRef, boolean hasMethod, + boolean isExpression, boolean isScript, BeanDefinition innerComponentDefinition) { + boolean isCustomBean = innerComponentDefinition != null; if (hasMethod && isScript) { @@ -219,89 +236,124 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar } BeanDefinitionBuilder valueProcessorBuilder = null; if (isValue) { - if (hasMethod) { - parserContext.getReaderContext().error( - "The 'method' attribute cannot be used with the 'value' attribute.", element); - } - if (IntegrationMessageHeaderAccessor.ROUTING_SLIP.equals(headerName)) { - List routingSlipPath = new ManagedList<>(); - routingSlipPath.addAll(Arrays.asList(StringUtils.tokenizeToStringArray(value, ";"))); - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(RoutingSlipHeaderValueMessageProcessor.class) - .addConstructorArgValue(routingSlipPath); - } - else { - Object headerValue = value; - - if (StringUtils.hasText(headerType)) { - TypedStringValue typedStringValue = new TypedStringValue(value); - typedStringValue.setTargetTypeName(headerType); - headerValue = typedStringValue; - } - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class) - .addConstructorArgValue(headerValue); - } + valueProcessorBuilder = value(element, parserContext, headerName, headerType, value, hasMethod); } else if (isExpression) { - if (hasMethod) { - parserContext.getReaderContext().error( - "The 'method' attribute cannot be used with the 'expression' attribute.", element); - } - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(ExpressionEvaluatingHeaderValueMessageProcessor.class); - if (expressionElement != null) { - BeanDefinitionBuilder dynamicExpressionBuilder = - BeanDefinitionBuilder.genericBeanDefinition(DynamicExpression.class); - dynamicExpressionBuilder.addConstructorArgValue(expressionElement.getAttribute("key")); - dynamicExpressionBuilder.addConstructorArgReference(expressionElement.getAttribute("source")); - valueProcessorBuilder.addConstructorArgValue(dynamicExpressionBuilder.getBeanDefinition()); - } - else { - valueProcessorBuilder.addConstructorArgValue(expression); - } - valueProcessorBuilder.addConstructorArgValue(headerType); + valueProcessorBuilder = expression(element, parserContext, headerType, expression, expressionElement, + hasMethod); } else if (isCustomBean) { - if (StringUtils.hasText(headerElement.getAttribute(TYPE_ATTRIBUTE))) { - parserContext.getReaderContext().error( - "The 'type' attribute cannot be used with an inner bean.", element); - } - if (hasMethod || isScript) { - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(MessageProcessingHeaderValueMessageProcessor.class) - .addConstructorArgValue(innerComponentDefinition); - if (hasMethod) { - valueProcessorBuilder.addConstructorArgValue(method); - } - } - else { - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class) - .addConstructorArgValue(innerComponentDefinition); - } + valueProcessorBuilder = innerComponentAndMethod(element, parserContext, headerElement, method, hasMethod, + isScript, innerComponentDefinition); } else { - if (StringUtils.hasText(headerElement.getAttribute(TYPE_ATTRIBUTE))) { - parserContext.getReaderContext().error( - "The 'type' attribute cannot be used with the 'ref' attribute.", element); - } - if (hasMethod) { - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(MessageProcessingHeaderValueMessageProcessor.class) - .addConstructorArgReference(ref) - .addConstructorArgValue(method); - } - else { - valueProcessorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class) - .addConstructorArgReference(ref); - } + valueProcessorBuilder = refAndMethod(element, parserContext, headerElement, ref, method, hasMethod); } if (StringUtils.hasText(overwrite)) { valueProcessorBuilder.addPropertyValue("overwrite", overwrite); } - headers.put(headerName, valueProcessorBuilder.getBeanDefinition()); + return valueProcessorBuilder; + } + + private BeanDefinitionBuilder value(Element element, ParserContext parserContext, String headerName, + String headerType, String value, boolean hasMethod) { + + BeanDefinitionBuilder valueProcessorBuilder; + if (hasMethod) { + parserContext.getReaderContext().error( + "The 'method' attribute cannot be used with the 'value' attribute.", element); + } + if (IntegrationMessageHeaderAccessor.ROUTING_SLIP.equals(headerName)) { + List routingSlipPath = new ManagedList<>(); + routingSlipPath.addAll(Arrays.asList(StringUtils.tokenizeToStringArray(value, ";"))); + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(RoutingSlipHeaderValueMessageProcessor.class) + .addConstructorArgValue(routingSlipPath); + } + else { + Object headerValue = value; + + if (StringUtils.hasText(headerType)) { + TypedStringValue typedStringValue = new TypedStringValue(value); + typedStringValue.setTargetTypeName(headerType); + headerValue = typedStringValue; + } + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class) + .addConstructorArgValue(headerValue); + } + return valueProcessorBuilder; + } + + private BeanDefinitionBuilder expression(Element element, ParserContext parserContext, String headerType, + String expression, Element expressionElement, boolean hasMethod) { + + BeanDefinitionBuilder valueProcessorBuilder; + if (hasMethod) { + parserContext.getReaderContext().error( + "The 'method' attribute cannot be used with the 'expression' attribute.", element); + } + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(ExpressionEvaluatingHeaderValueMessageProcessor.class); + if (expressionElement != null) { + BeanDefinitionBuilder dynamicExpressionBuilder = + BeanDefinitionBuilder.genericBeanDefinition(DynamicExpression.class); + dynamicExpressionBuilder.addConstructorArgValue(expressionElement.getAttribute("key")); + dynamicExpressionBuilder.addConstructorArgReference(expressionElement.getAttribute("source")); + valueProcessorBuilder.addConstructorArgValue(dynamicExpressionBuilder.getBeanDefinition()); + } + else { + valueProcessorBuilder.addConstructorArgValue(expression); + } + valueProcessorBuilder.addConstructorArgValue(headerType); + return valueProcessorBuilder; + } + + private BeanDefinitionBuilder innerComponentAndMethod(Element element, ParserContext parserContext, + Element headerElement, String method, boolean hasMethod, boolean isScript, + BeanDefinition innerComponentDefinition) { + + BeanDefinitionBuilder valueProcessorBuilder; + if (StringUtils.hasText(headerElement.getAttribute(TYPE_ATTRIBUTE))) { + parserContext.getReaderContext().error( + "The 'type' attribute cannot be used with an inner bean.", element); + } + if (hasMethod || isScript) { + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(MessageProcessingHeaderValueMessageProcessor.class) + .addConstructorArgValue(innerComponentDefinition); + if (hasMethod) { + valueProcessorBuilder.addConstructorArgValue(method); + } + } + else { + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class) + .addConstructorArgValue(innerComponentDefinition); + } + return valueProcessorBuilder; + } + + private BeanDefinitionBuilder refAndMethod(Element element, ParserContext parserContext, Element headerElement, + String ref, String method, boolean hasMethod) { + + BeanDefinitionBuilder valueProcessorBuilder; + if (StringUtils.hasText(headerElement.getAttribute(TYPE_ATTRIBUTE))) { + parserContext.getReaderContext().error( + "The 'type' attribute cannot be used with the 'ref' attribute.", element); + } + if (hasMethod) { + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(MessageProcessingHeaderValueMessageProcessor.class) + .addConstructorArgReference(ref) + .addConstructorArgValue(method); + } + else { + valueProcessorBuilder = + BeanDefinitionBuilder.genericBeanDefinition(StaticHeaderValueMessageProcessor.class) + .addConstructorArgReference(ref); + } + return valueProcessorBuilder; } /** diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IdempotentReceiverInterceptorParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IdempotentReceiverInterceptorParser.java index d36dae5e4b..e33186510a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IdempotentReceiverInterceptorParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IdempotentReceiverInterceptorParser.java @@ -37,11 +37,12 @@ import org.springframework.util.StringUtils; * Parser for the <idempotent-receiver/> element. * * @author Artem Bilan + * @author Gary Russell * @since 4.1 */ public class IdempotentReceiverInterceptorParser extends AbstractBeanDefinitionParser { - @Override + @Override // NOSONAR complexity protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { Object source = parserContext.extractSource(element); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PointToPointChannelParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PointToPointChannelParser.java index 0651d061c0..465b9a6c04 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PointToPointChannelParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PointToPointChannelParser.java @@ -53,48 +53,10 @@ public class PointToPointChannelParser extends AbstractChannelParser { // configure a queue-based channel if any queue sub-element is defined String channel = element.getAttribute(ID_ATTRIBUTE); if ((queueElement = DomUtils.getChildElementByTagName(element, "queue")) != null) { // NOSONAR inner assignment - builder = BeanDefinitionBuilder.genericBeanDefinition(QueueChannel.class); - boolean hasStoreRef = this.parseStoreRef(builder, queueElement, channel, false); - boolean hasQueueRef = this.parseQueueRef(builder, queueElement); - if (!hasStoreRef || !hasQueueRef) { - boolean hasCapacity = this.parseQueueCapacity(builder, queueElement); - if (hasCapacity && hasQueueRef) { - parserContext.getReaderContext().error( - "The 'capacity' attribute is not allowed when providing a 'ref' to a custom queue.", - element); - } - if (hasCapacity && hasStoreRef) { - parserContext.getReaderContext().error( - "The 'capacity' attribute is not allowed" + - " when providing a 'message-store' to a custom MessageGroupStore.", - element); - } - } - if (hasStoreRef && hasQueueRef) { - parserContext.getReaderContext().error( - "The 'message-store' attribute is not allowed when providing a 'ref' to a custom queue.", - element); - } + builder = queue(element, parserContext, queueElement, channel); } else if ((queueElement = DomUtils.getChildElementByTagName(element, "priority-queue")) != null) { // NOSONAR - builder = BeanDefinitionBuilder.genericBeanDefinition(PriorityChannel.class); - boolean hasCapacity = this.parseQueueCapacity(builder, queueElement); - String comparatorRef = queueElement.getAttribute("comparator"); - if (StringUtils.hasText(comparatorRef)) { - builder.addConstructorArgReference(comparatorRef); - } - if (parseStoreRef(builder, queueElement, channel, true)) { - if (StringUtils.hasText(comparatorRef)) { - parserContext.getReaderContext().error( - "The 'message-store' attribute is not allowed" + - " when providing a 'comparator' to a priority queue.", - element); - } - if (hasCapacity) { - parserContext.getReaderContext().error("The 'capacity' attribute is not allowed" - + " when providing a 'message-store' to a custom MessageGroupStore.", element); - } - } + builder = priorityQueue(element, parserContext, queueElement, channel); } else if ((queueElement = DomUtils.getChildElementByTagName(element, "rendezvous-queue")) != null) { // NOSONAR @@ -125,45 +87,107 @@ public class PointToPointChannelParser extends AbstractChannelParser { : DirectChannel.class); } else { - if (isFixedSubscriber) { - parserContext.getReaderContext().error( - "The 'fixed-subscriber' attribute is not allowed" + - " when a child element is present.", - element); - } - // configure either an ExecutorChannel or DirectChannel based on existence of 'task-executor' - String taskExecutor = dispatcherElement.getAttribute("task-executor"); - if (StringUtils.hasText(taskExecutor)) { - builder = BeanDefinitionBuilder.genericBeanDefinition(ExecutorChannel.class); - builder.addConstructorArgReference(taskExecutor); - } - else { - builder = BeanDefinitionBuilder.genericBeanDefinition(DirectChannel.class); - } - // unless the 'load-balancer' attribute is explicitly set to 'none' - // or 'load-balancer-ref' is explicitly configured, - // configure the default RoundRobinLoadBalancingStrategy - String loadBalancer = dispatcherElement.getAttribute("load-balancer"); - String loadBalancerRef = dispatcherElement.getAttribute("load-balancer-ref"); - if (StringUtils.hasText(loadBalancer) && StringUtils.hasText(loadBalancerRef)) { - parserContext.getReaderContext().error("'load-balancer' and 'load-balancer-ref' are mutually exclusive", - element); - } - if (StringUtils.hasText(loadBalancerRef)) { - builder.addConstructorArgReference(loadBalancerRef); - } - else { - if ("none".equals(loadBalancer)) { - builder.addConstructorArgValue(null); - } - } - - IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, dispatcherElement, "failover"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, dispatcherElement, "max-subscribers"); + builder = dispatcher(element, parserContext, isFixedSubscriber, dispatcherElement); } return builder; } + private BeanDefinitionBuilder queue(Element element, ParserContext parserContext, Element queueElement, + String channel) { + + BeanDefinitionBuilder builder; + builder = BeanDefinitionBuilder.genericBeanDefinition(QueueChannel.class); + boolean hasStoreRef = this.parseStoreRef(builder, queueElement, channel, false); + boolean hasQueueRef = this.parseQueueRef(builder, queueElement); + if (!hasStoreRef || !hasQueueRef) { + boolean hasCapacity = this.parseQueueCapacity(builder, queueElement); + if (hasCapacity && hasQueueRef) { + parserContext.getReaderContext().error( + "The 'capacity' attribute is not allowed when providing a 'ref' to a custom queue.", + element); + } + if (hasCapacity && hasStoreRef) { + parserContext.getReaderContext().error( + "The 'capacity' attribute is not allowed" + + " when providing a 'message-store' to a custom MessageGroupStore.", + element); + } + } + if (hasStoreRef && hasQueueRef) { + parserContext.getReaderContext().error( + "The 'message-store' attribute is not allowed when providing a 'ref' to a custom queue.", + element); + } + return builder; + } + + private BeanDefinitionBuilder priorityQueue(Element element, ParserContext parserContext, Element queueElement, + String channel) { + + BeanDefinitionBuilder builder; + builder = BeanDefinitionBuilder.genericBeanDefinition(PriorityChannel.class); + boolean hasCapacity = this.parseQueueCapacity(builder, queueElement); + String comparatorRef = queueElement.getAttribute("comparator"); + if (StringUtils.hasText(comparatorRef)) { + builder.addConstructorArgReference(comparatorRef); + } + if (parseStoreRef(builder, queueElement, channel, true)) { + if (StringUtils.hasText(comparatorRef)) { + parserContext.getReaderContext().error( + "The 'message-store' attribute is not allowed" + + " when providing a 'comparator' to a priority queue.", + element); + } + if (hasCapacity) { + parserContext.getReaderContext().error("The 'capacity' attribute is not allowed" + + " when providing a 'message-store' to a custom MessageGroupStore.", element); + } + } + return builder; + } + + private BeanDefinitionBuilder dispatcher(Element element, ParserContext parserContext, boolean isFixedSubscriber, + Element dispatcherElement) { + + BeanDefinitionBuilder builder; + if (isFixedSubscriber) { + parserContext.getReaderContext().error( + "The 'fixed-subscriber' attribute is not allowed" + + " when a child element is present.", + element); + } + // configure either an ExecutorChannel or DirectChannel based on existence of 'task-executor' + String taskExecutor = dispatcherElement.getAttribute("task-executor"); + if (StringUtils.hasText(taskExecutor)) { + builder = BeanDefinitionBuilder.genericBeanDefinition(ExecutorChannel.class); + builder.addConstructorArgReference(taskExecutor); + } + else { + builder = BeanDefinitionBuilder.genericBeanDefinition(DirectChannel.class); + } + // unless the 'load-balancer' attribute is explicitly set to 'none' + // or 'load-balancer-ref' is explicitly configured, + // configure the default RoundRobinLoadBalancingStrategy + String loadBalancer = dispatcherElement.getAttribute("load-balancer"); + String loadBalancerRef = dispatcherElement.getAttribute("load-balancer-ref"); + if (StringUtils.hasText(loadBalancer) && StringUtils.hasText(loadBalancerRef)) { + parserContext.getReaderContext().error("'load-balancer' and 'load-balancer-ref' are mutually exclusive", + element); + } + if (StringUtils.hasText(loadBalancerRef)) { + builder.addConstructorArgReference(loadBalancerRef); + } + else { + if ("none".equals(loadBalancer)) { + builder.addConstructorArgValue(null); + } + } + + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, dispatcherElement, "failover"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, dispatcherElement, "max-subscribers"); + return builder; + } + private boolean parseQueueCapacity(BeanDefinitionBuilder builder, Element queueElement) { String capacity = queueElement.getAttribute("capacity"); if (StringUtils.hasText(capacity)) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java index c9a5af0262..0bbc2113f4 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PollerParser.java @@ -118,42 +118,16 @@ public class PollerParser extends AbstractBeanDefinitionParser { List triggerBeanNames = new ArrayList(); if (StringUtils.hasText(triggerAttribute)) { - if (StringUtils.hasText(timeUnit)) { - parserContext.getReaderContext().error("The 'time-unit' attribute cannot be used with a 'trigger' reference.", pollerElement); - } - triggerBeanNames.add(triggerAttribute); + trigger(pollerElement, parserContext, triggerAttribute, timeUnit, triggerBeanNames); } if (StringUtils.hasText(fixedRateAttribute)) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PeriodicTrigger.class); - builder.addConstructorArgValue(fixedRateAttribute); - if (StringUtils.hasText(timeUnit)) { - builder.addConstructorArgValue(timeUnit); - } - builder.addPropertyValue("fixedRate", Boolean.TRUE); - String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName( - builder.getBeanDefinition(), parserContext.getRegistry()); - triggerBeanNames.add(triggerBeanName); + fixedRate(parserContext, fixedRateAttribute, timeUnit, triggerBeanNames); } if (StringUtils.hasText(fixedDelayAttribute)) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PeriodicTrigger.class); - builder.addConstructorArgValue(fixedDelayAttribute); - if (StringUtils.hasText(timeUnit)) { - builder.addConstructorArgValue(timeUnit); - } - builder.addPropertyValue("fixedRate", Boolean.FALSE); - String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName( - builder.getBeanDefinition(), parserContext.getRegistry()); - triggerBeanNames.add(triggerBeanName); + fixedDelay(parserContext, fixedDelayAttribute, timeUnit, triggerBeanNames); } if (StringUtils.hasText(cronAttribute)) { - if (StringUtils.hasText(timeUnit)) { - parserContext.getReaderContext().error("The 'time-unit' attribute cannot be used with a 'cron' trigger.", pollerElement); - } - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CronTrigger.class); - builder.addConstructorArgValue(cronAttribute); - String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName( - builder.getBeanDefinition(), parserContext.getRegistry()); - triggerBeanNames.add(triggerBeanName); + cron(pollerElement, parserContext, cronAttribute, timeUnit, triggerBeanNames); } if (triggerBeanNames.isEmpty()) { parserContext.getReaderContext().error(NO_TRIGGER_DEFINITIONS, pollerElement); @@ -163,4 +137,54 @@ public class PollerParser extends AbstractBeanDefinitionParser { } targetBuilder.addPropertyReference("trigger", triggerBeanNames.get(0)); } + + private void trigger(Element pollerElement, ParserContext parserContext, String triggerAttribute, String timeUnit, + List triggerBeanNames) { + + if (StringUtils.hasText(timeUnit)) { + parserContext.getReaderContext().error("The 'time-unit' attribute cannot be used with a 'trigger' reference.", pollerElement); + } + triggerBeanNames.add(triggerAttribute); + } + + private void fixedRate(ParserContext parserContext, String fixedRateAttribute, String timeUnit, + List triggerBeanNames) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PeriodicTrigger.class); + builder.addConstructorArgValue(fixedRateAttribute); + if (StringUtils.hasText(timeUnit)) { + builder.addConstructorArgValue(timeUnit); + } + builder.addPropertyValue("fixedRate", Boolean.TRUE); + String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName( + builder.getBeanDefinition(), parserContext.getRegistry()); + triggerBeanNames.add(triggerBeanName); + } + + private void fixedDelay(ParserContext parserContext, String fixedDelayAttribute, String timeUnit, + List triggerBeanNames) { + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PeriodicTrigger.class); + builder.addConstructorArgValue(fixedDelayAttribute); + if (StringUtils.hasText(timeUnit)) { + builder.addConstructorArgValue(timeUnit); + } + builder.addPropertyValue("fixedRate", Boolean.FALSE); + String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName( + builder.getBeanDefinition(), parserContext.getRegistry()); + triggerBeanNames.add(triggerBeanName); + } + + private void cron(Element pollerElement, ParserContext parserContext, String cronAttribute, String timeUnit, + List triggerBeanNames) { + + if (StringUtils.hasText(timeUnit)) { + parserContext.getReaderContext().error("The 'time-unit' attribute cannot be used with a 'cron' trigger.", + pollerElement); + } + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CronTrigger.class); + builder.addConstructorArgValue(cronAttribute); + String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName( + builder.getBeanDefinition(), parserContext.getRegistry()); + triggerBeanNames.add(triggerBeanName); + } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PublishingInterceptorParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PublishingInterceptorParser.java index 7797696a3c..01a2796bd3 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PublishingInterceptorParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PublishingInterceptorParser.java @@ -88,31 +88,7 @@ public class PublishingInterceptorParser extends AbstractBeanDefinitionParser { payloadExpressionMap.put(methodPattern, payloadExpression); // set headersMap - List headerElements = DomUtils.getChildElementsByTagName(mapping, "header"); - Map headerExpressions = new HashMap<>(); - for (Element headerElement : headerElements) { - String name = headerElement.getAttribute("name"); - if (!StringUtils.hasText(name)) { - parserContext.getReaderContext() - .error("the 'name' attribute is required on the
element", - parserContext.extractSource(headerElement)); - continue; - } - String value = headerElement.getAttribute("value"); - String expression = headerElement.getAttribute("expression"); - boolean hasValue = StringUtils.hasText(value); - boolean hasExpression = StringUtils.hasText(expression); - if (hasValue == hasExpression) { - parserContext.getReaderContext() - .error("exactly one of 'value' or 'expression' is required on the
element", - parserContext.extractSource(headerElement)); - continue; - } - if (hasValue) { - expression = "'" + value + "'"; - } - headerExpressions.put(name, expression); - } + Map headerExpressions = headerExpressions(parserContext, mapping); if (headerExpressions.size() > 0) { headersExpressionMap.put(methodPattern, headerExpressions); } @@ -138,4 +114,33 @@ public class PublishingInterceptorParser extends AbstractBeanDefinitionParser { return interceptorMappings; } + private Map headerExpressions(ParserContext parserContext, Element mapping) { + List headerElements = DomUtils.getChildElementsByTagName(mapping, "header"); + Map headerExpressions = new HashMap<>(); + for (Element headerElement : headerElements) { + String name = headerElement.getAttribute("name"); + if (!StringUtils.hasText(name)) { + parserContext.getReaderContext() + .error("the 'name' attribute is required on the
element", + parserContext.extractSource(headerElement)); + continue; + } + String value = headerElement.getAttribute("value"); + String expression = headerElement.getAttribute("expression"); + boolean hasValue = StringUtils.hasText(value); + boolean hasExpression = StringUtils.hasText(expression); + if (hasValue == hasExpression) { + parserContext.getReaderContext() + .error("exactly one of 'value' or 'expression' is required on the
element", + parserContext.extractSource(headerElement)); + continue; + } + if (hasValue) { + expression = "'" + value + "'"; + } + headerExpressions.put(name, expression); + } + return headerExpressions; + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ScatterGatherParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ScatterGatherParser.java index f1f4d867db..ab6c70e3ba 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ScatterGatherParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ScatterGatherParser.java @@ -68,6 +68,22 @@ public class ScatterGatherParser extends AbstractConsumerEndpointParser { AbstractBeanDefinition scatterGatherDefinition = builder.getRawBeanDefinition(); String id = resolveId(element, scatterGatherDefinition, parserContext); + scatter(parserContext, scatterChannel, hasScatterChannel, scatterer, hasScatterer, builder, + scatterGatherDefinition, id); + + gather(element, parserContext, builder, scatterGatherDefinition, id); + + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "gather-channel"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "gather-timeout"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply"); + + return builder; + } + + private void scatter(ParserContext parserContext, String scatterChannel, boolean hasScatterChannel, + Element scatterer, boolean hasScatterer, BeanDefinitionBuilder builder, + AbstractBeanDefinition scatterGatherDefinition, String id) { + if (hasScatterChannel) { builder.addConstructorArgReference(scatterChannel); } @@ -89,6 +105,10 @@ public class ScatterGatherParser extends AbstractConsumerEndpointParser { parserContext.getRegistry().registerBeanDefinition(scattererId, scattererDefinition); // NOSONAR not null builder.addConstructorArgValue(new RuntimeBeanReference(scattererId)); } + } + + private void gather(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, + AbstractBeanDefinition scatterGatherDefinition, String id) { Element gatherer = DomUtils.getChildElementByTagName(element, "gatherer"); @@ -111,12 +131,6 @@ public class ScatterGatherParser extends AbstractConsumerEndpointParser { } parserContext.getRegistry().registerBeanDefinition(gathererId, gathererDefinition); // NOSONAR not null builder.addConstructorArgValue(new RuntimeBeanReference(gathererId)); - - IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "gather-channel"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "gather-timeout"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply"); - - return builder; } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/BroadcastingDispatcher.java b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/BroadcastingDispatcher.java index 383c625f3e..36be406d6f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/BroadcastingDispatcher.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/BroadcastingDispatcher.java @@ -146,7 +146,7 @@ public class BroadcastingDispatcher extends AbstractDispatcher implements BeanFa return this.messageBuilderFactory; } - @Override + @Override // NOSONAR complexity public boolean dispatch(Message message) { int dispatched = 0; int sequenceNumber = 1; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java index d3d4f13994..7673279d8c 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java @@ -137,7 +137,7 @@ public class IntegrationFlowBeanPostProcessor } } - private Object processStandardIntegrationFlow(StandardIntegrationFlow flow, String flowBeanName) { + private Object processStandardIntegrationFlow(StandardIntegrationFlow flow, String flowBeanName) { // NOSONAR complexity String flowNamePrefix = flowBeanName + "."; if (this.flowContext == null) { this.flowContext = this.beanFactory.getBean(IntegrationFlowContext.class); @@ -354,7 +354,7 @@ public class IntegrationFlowBeanPostProcessor } } - private void invokeBeanInitializationHooks(final String beanName, final Object bean) { + private void invokeBeanInitializationHooks(final String beanName, final Object bean) { // NOSONAR complexity if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowLifecycleAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowLifecycleAdvice.java index 4a1aa6e4df..fc27e7b74f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowLifecycleAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowLifecycleAdvice.java @@ -79,48 +79,53 @@ class IntegrationFlowLifecycleAdvice implements MethodInterceptor { if (target instanceof SmartLifecycle) { result = invocation.proceed(); } - - switch (method) { - - case "start": - this.delegate.start(); - break; - - case "stop": - Object[] arguments = invocation.getArguments(); - if (!ObjectUtils.isEmpty(arguments)) { - this.delegate.stop((Runnable) arguments[0]); - } - else { - this.delegate.stop(); - } - break; - - case "isRunning": - if (result == null) { - result = this.delegate.isRunning(); - } - break; - - case "isAutoStartup": - if (result == null) { - result = this.delegate.isAutoStartup(); - } - break; - - case "getPhase": - if (result == null) { - result = this.delegate.getPhase(); - } - break; - - default: - break; - - } + result = applyToDelegate(invocation, method, result); } return result; } + private Object applyToDelegate(MethodInvocation invocation, String method, Object resultArg) { + Object result = resultArg; + switch (method) { + + case "start": + this.delegate.start(); + break; + + case "stop": + Object[] arguments = invocation.getArguments(); + if (!ObjectUtils.isEmpty(arguments)) { + this.delegate.stop((Runnable) arguments[0]); + } + else { + this.delegate.stop(); + } + break; + + case "isRunning": + if (result == null) { + result = this.delegate.isRunning(); + } + break; + + case "isAutoStartup": + if (result == null) { + result = this.delegate.isAutoStartup(); + } + break; + + case "getPhase": + if (result == null) { + result = this.delegate.getPhase(); + } + break; + + default: + break; + + } + return result; + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java index 99d4317da7..a8d42b5beb 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java @@ -268,14 +268,15 @@ public final class StandardIntegrationFlowContext implements IntegrationFlowCont } /** - * The {@code boolean} flag to indication if an {@link IntegrationFlow} must be started - * automatically after registration. Defaults to {@code true}. - * @param autoStartup start or not the {@link IntegrationFlow} automatically after registration. + * The {@code boolean} flag to indication if an {@link IntegrationFlow} must be + * started automatically after registration. Defaults to {@code true}. + * @param autoStartupToSet start or not the {@link IntegrationFlow} automatically + * after registration. * @return the current builder instance */ @Override - public StandardIntegrationFlowRegistrationBuilder autoStartup(boolean autoStartup) { - this.autoStartup = autoStartup; + public StandardIntegrationFlowRegistrationBuilder autoStartup(boolean autoStartupToSet) { + this.autoStartup = autoStartupToSet; return this; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractFetchLimitingMessageSource.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractFetchLimitingMessageSource.java index 8877701795..0232cfa6e0 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractFetchLimitingMessageSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractFetchLimitingMessageSource.java @@ -49,10 +49,10 @@ public abstract class AbstractFetchLimitingMessageSource extends AbstractMess * Subclasses must implement this method. Typically the returned value will be the * payload of type T, but the returned value may also be a Message instance whose * payload is of type T. - * @param maxFetchSize the maximum number of messages to fetch if a fetch is + * @param maxFetchSizeToReceive the maximum number of messages to fetch if a fetch is * necessary. * @return The value returned. */ - protected abstract Object doReceive(int maxFetchSize); + protected abstract Object doReceive(int maxFetchSizeToReceive); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java index cb123c394f..0ccb496fa2 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractMessageSource.java @@ -75,8 +75,8 @@ public abstract class AbstractMessageSource extends AbstractExpressionEvaluat } @Override - public void registerMetricsCaptor(MetricsCaptor metricsCaptor) { - this.metricsCaptor = metricsCaptor; + public void registerMetricsCaptor(MetricsCaptor metricsCaptorToSet) { + this.metricsCaptor = metricsCaptorToSet; } @Override diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java index 41855b4c3a..d15315983d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java @@ -320,7 +320,7 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement new Date()) )), 1) .repeat(this::isRunning) - .doOnSubscribe(subscription -> this.subscription = subscription); + .doOnSubscribe(subs -> this.subscription = subs); } private Message pollForMessage() { @@ -377,31 +377,35 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement return null; } else { - if (this.logger.isDebugEnabled()) { - this.logger.debug("Poll resulted in Message: " + message); - } - if (holder != null) { - holder.setMessage(message); - } - - if (!isReactive()) { - try { - handleMessage(message); - } - catch (Exception e) { - if (e instanceof MessagingException) { - throw new MessagingExceptionWrapper(message, (MessagingException) e); - } - else { - throw new MessagingException(message, e); - } - } - } + messageReceived(holder, message); } return message; } + private void messageReceived(IntegrationResourceHolder holder, Message message) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Poll resulted in Message: " + message); + } + if (holder != null) { + holder.setMessage(message); + } + + if (!isReactive()) { + try { + handleMessage(message); + } + catch (Exception e) { + if (e instanceof MessagingException) { + throw new MessagingExceptionWrapper(message, (MessagingException) e); + } + else { + throw new MessagingException(message, e); + } + } + } + } + @Override // guarded by super#lifecycleLock protected void doStop() { if (this.runningTask != null) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/expression/ReloadableResourceBundleExpressionSource.java b/spring-integration-core/src/main/java/org/springframework/integration/expression/ReloadableResourceBundleExpressionSource.java index ae664e5050..e78bc29563 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/expression/ReloadableResourceBundleExpressionSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/expression/ReloadableResourceBundleExpressionSource.java @@ -414,10 +414,7 @@ public class ReloadableResourceBundleExpressionSource implements ExpressionSourc PropertiesHolder propHolder = propHolderArg; long refreshTimestamp = (this.cacheMillis < 0) ? -1 : System.currentTimeMillis(); - Resource resource = this.resourceLoader.getResource(filename + PROPERTIES_SUFFIX); - if (!resource.exists()) { - resource = this.resourceLoader.getResource(filename + XML_SUFFIX); - } + Resource resource = getResource(filename); if (resource.exists()) { long fileTimestamp = -1; @@ -427,7 +424,8 @@ public class ReloadableResourceBundleExpressionSource implements ExpressionSourc fileTimestamp = resource.lastModified(); if (propHolder != null && propHolder.getFileTimestamp() == fileTimestamp) { if (logger.isDebugEnabled()) { - logger.debug("Re-caching properties for filename [" + filename + "] - file hasn't been modified"); + logger.debug("Re-caching properties for filename [" + filename + + "] - file hasn't been modified"); } propHolder.setRefreshTimestamp(refreshTimestamp); return propHolder; @@ -436,23 +434,13 @@ public class ReloadableResourceBundleExpressionSource implements ExpressionSourc catch (IOException ex) { // Probably a class path resource: cache it forever. if (logger.isDebugEnabled()) { - logger.debug( - resource + " could not be resolved in the file system - assuming that is hasn't changed", ex); + logger.debug(resource + + " could not be resolved in the file system - assuming that is hasn't changed", ex); } fileTimestamp = -1; } } - try { - Properties props = loadProperties(resource, filename); - propHolder = new PropertiesHolder(props, fileTimestamp); - } - catch (IOException ex) { - if (logger.isWarnEnabled()) { - logger.warn("Could not parse properties file [" + resource.getFilename() + "]", ex); - } - // Empty holder representing "not valid". - propHolder = new PropertiesHolder(); - } + propHolder = load(filename, resource, fileTimestamp); } else { @@ -469,6 +457,30 @@ public class ReloadableResourceBundleExpressionSource implements ExpressionSourc return propHolder; } + private Resource getResource(String filename) { + Resource resource = this.resourceLoader.getResource(filename + PROPERTIES_SUFFIX); + if (!resource.exists()) { + resource = this.resourceLoader.getResource(filename + XML_SUFFIX); + } + return resource; + } + + private PropertiesHolder load(String filename, Resource resource, long fileTimestamp) { + PropertiesHolder propHolder; + try { + Properties props = loadProperties(resource, filename); + propHolder = new PropertiesHolder(props, fileTimestamp); + } + catch (IOException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Could not parse properties file [" + resource.getFilename() + "]", ex); + } + // Empty holder representing "not valid". + propHolder = new PropertiesHolder(); + } + return propHolder; + } + /** * Load the properties from the given resource. * @param resource the resource to load from diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMethodInboundMessageMapper.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMethodInboundMessageMapper.java index 7b5777bc86..ef6558e86a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMethodInboundMessageMapper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMethodInboundMessageMapper.java @@ -285,18 +285,18 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper toMessage(MethodArgsHolder holder, @Nullable Map headers) { + public Message toMessage(MethodArgsHolder holder, @Nullable Map headersToMap) { Object messageOrPayload = null; boolean foundPayloadAnnotation = false; Object[] arguments = holder.getArgs(); EvaluationContext methodInvocationEvaluationContext = createMethodInvocationEvaluationContext(arguments); Map headersToPopulate = - headers != null - ? new HashMap<>(headers) + headersToMap != null + ? new HashMap<>(headersToMap) : new HashMap<>(); if (GatewayMethodInboundMessageMapper.this.payloadExpression != null) { messageOrPayload = @@ -315,11 +315,8 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper headersToPopulate, Object argumentValue, + MethodParameter methodParameter, Annotation annotation) { + if (annotation.annotationType().equals(Header.class)) { + processHeaderAnnotation(headersToPopulate, argumentValue, methodParameter, annotation); + } + else if (annotation.annotationType().equals(Headers.class)) { + processHeadersAnnotation(headersToPopulate, argumentValue); + } + } + @Nullable private Object processPayloadAnnotation(@Nullable Object messageOrPayload, Object argumentValue, MethodParameter methodParameter, Annotation annotation) { @@ -417,8 +424,8 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper builder = (messageOrPayload instanceof Message) - ? this.messageBuilderFactory.fromMessage((Message) messageOrPayload) - : this.messageBuilderFactory.withPayload(messageOrPayload); + ? this.msgBuilderFactory.fromMessage((Message) messageOrPayload) + : this.msgBuilderFactory.withPayload(messageOrPayload); builder.copyHeadersIfAbsent(headers); // Explicit headers in XML override any @Header annotations... if (!CollectionUtils.isEmpty(GatewayMethodInboundMessageMapper.this.headerExpressions)) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java index 2ab68b67de..279839de80 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java @@ -30,6 +30,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.Future; +import java.util.function.Consumer; import java.util.function.Supplier; import org.aopalliance.intercept.MethodInterceptor; @@ -61,6 +62,7 @@ import org.springframework.integration.expression.ValueExpression; import org.springframework.integration.support.DefaultMessageBuilderFactory; import org.springframework.integration.support.channel.ChannelResolverUtils; import org.springframework.integration.support.management.TrackableComponent; +import org.springframework.integration.util.JavaUtils; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; @@ -492,17 +494,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint boolean shouldReply = returnType != void.class; int paramCount = method.getParameterTypes().length; Object response = null; - boolean hasPayloadExpression = method.isAnnotationPresent(Payload.class); - if (!hasPayloadExpression) { - // check for the method metadata next - if (this.methodMetadataMap != null) { - GatewayMethodMetadata metadata = this.methodMetadataMap.get(method.getName()); - hasPayloadExpression = (metadata != null) && StringUtils.hasText(metadata.getPayloadExpression()); - } - else if (this.globalMethodMetadata != null) { - hasPayloadExpression = StringUtils.hasText(this.globalMethodMetadata.getPayloadExpression()); - } - } + boolean hasPayloadExpression = findPayloadExpression(method); if (paramCount == 0 && !hasPayloadExpression) { Long receiveTimeout = null; if (gateway.getReceiveTimeoutExpression() != null) { @@ -526,16 +518,49 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } } else { - Object[] args = invocation.getArguments(); - if (shouldReply) { - response = shouldReturnMessage ? gateway.sendAndReceiveMessage(args) : gateway.sendAndReceive(args); + response = sendOrSendAndReceive(invocation, gateway, shouldReturnMessage, shouldReply); + } + return response(returnType, shouldReturnMessage, response); + } + + @Nullable + private Object response(Class returnType, boolean shouldReturnMessage, @Nullable Object response) { + if (shouldReturnMessage) { + return response; + } + else { + return response != null ? convert(response, returnType) : null; + } + } + + private boolean findPayloadExpression(Method method) { + boolean hasPayloadExpression = method.isAnnotationPresent(Payload.class); + if (!hasPayloadExpression) { + // check for the method metadata next + if (this.methodMetadataMap != null) { + GatewayMethodMetadata metadata = this.methodMetadataMap.get(method.getName()); + hasPayloadExpression = (metadata != null) && StringUtils.hasText(metadata.getPayloadExpression()); } - else { - gateway.send(args); - response = null; + else if (this.globalMethodMetadata != null) { + hasPayloadExpression = StringUtils.hasText(this.globalMethodMetadata.getPayloadExpression()); } } - return (response != null) ? this.convert(response, returnType) : null; + return hasPayloadExpression; + } + + @Nullable + private Object sendOrSendAndReceive(MethodInvocation invocation, MethodInvocationGateway gateway, + boolean shouldReturnMessage, boolean shouldReply) { + Object response; + Object[] args = invocation.getArguments(); + if (shouldReply) { + response = shouldReturnMessage ? gateway.sendAndReceiveMessage(args) : gateway.sendAndReceive(args); + } + else { + gateway.send(args); + response = null; + } + return response; } private void rethrowExceptionCauseIfPossible(Throwable originalException, Method method) throws Throwable { // NOSONAR @@ -594,23 +619,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint payloadExpression = gatewayAnnotation.payloadExpression(); } - if (!ObjectUtils.isEmpty(gatewayAnnotation.headers())) { - for (GatewayHeader gatewayHeader : gatewayAnnotation.headers()) { - String value = gatewayHeader.value(); - String expression = gatewayHeader.expression(); - String name = gatewayHeader.name(); - boolean hasValue = StringUtils.hasText(value); - - if (hasValue == StringUtils.hasText(expression)) { - throw new BeanDefinitionStoreException("exactly one of 'value' or 'expression' " + - "is required on a gateway's header."); - } - headerExpressions.put(name, hasValue - ? new LiteralExpression(value) - : EXPRESSION_PARSER.parseExpression(expression)); - } - } - + annotationHeaders(gatewayAnnotation, headerExpressions); } else if (this.methodMetadataMap != null && this.methodMetadataMap.size() > 0) { GatewayMethodMetadata methodMetadata = this.methodMetadataMap.get(method.getName()); @@ -633,6 +642,57 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } } } + Map headers = headers(method, headerExpressions); + + GatewayMethodInboundMessageMapper messageMapper = new GatewayMethodInboundMessageMapper(method, + headerExpressions, + this.globalMethodMetadata != null ? this.globalMethodMetadata.getHeaderExpressions() : null, + headers, this.argsMapper, this.getMessageBuilderFactory()); + MethodInvocationGateway gateway = new MethodInvocationGateway(messageMapper); + + JavaUtils.INSTANCE + .acceptIfHasText(payloadExpression, messageMapper::setPayloadExpression) + .acceptIfNotNull(getTaskScheduler(), gateway::setTaskScheduler); + gateway.setBeanName(this.getComponentName()); + + setChannel(this.errorChannel, gateway::setErrorChannel, this.errorChannelName, gateway::setErrorChannelName); + setChannel(requestChannelName, this.defaultRequestChannelName, gateway::setRequestChannelName, + this.defaultRequestChannel, gateway::setRequestChannel); + setChannel(replyChannelName, this.defaultReplyChannelName, gateway::setReplyChannelName, + this.defaultReplyChannel, gateway::setReplyChannel); + + timeouts(requestTimeout, replyTimeout, messageMapper, gateway); + BeanFactory beanFactory = this.getBeanFactory(); + if (beanFactory != null) { + gateway.setBeanFactory(beanFactory); + messageMapper.setBeanFactory(beanFactory); + } + gateway.setShouldTrack(this.shouldTrack); + gateway.afterPropertiesSet(); + return gateway; + } + + private void annotationHeaders(Gateway gatewayAnnotation, Map headerExpressions) { + if (!ObjectUtils.isEmpty(gatewayAnnotation.headers())) { + for (GatewayHeader gatewayHeader : gatewayAnnotation.headers()) { + String value = gatewayHeader.value(); + String expression = gatewayHeader.expression(); + String name = gatewayHeader.name(); + boolean hasValue = StringUtils.hasText(value); + + if (hasValue == StringUtils.hasText(expression)) { + throw new BeanDefinitionStoreException("exactly one of 'value' or 'expression' " + + "is required on a gateway's header."); + } + headerExpressions.put(name, hasValue + ? new LiteralExpression(value) + : EXPRESSION_PARSER.parseExpression(expression)); + } + } + } + + @Nullable + private Map headers(Method method, Map headerExpressions) { Map headers = null; // We don't want to eagerly resolve the error channel here Object errorChannelForVoidReturn = this.errorChannel == null ? this.errorChannelName : this.errorChannel; @@ -658,57 +718,23 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } } - for (String header : headerNames) { - if ((MessageHeaders.ID.equals(header) || MessageHeaders.TIMESTAMP.equals(header))) { - throw new BeanInitializationException( - "Messaging Gateway cannot override 'id' and 'timestamp' read-only headers.\n" + - "Wrong headers configuration for " + getComponentName()); - } + validateHeaders(headerNames); + } + return headers; + } + + private void validateHeaders(Set headerNames) { + for (String header : headerNames) { + if ((MessageHeaders.ID.equals(header) || MessageHeaders.TIMESTAMP.equals(header))) { + throw new BeanInitializationException( + "Messaging Gateway cannot override 'id' and 'timestamp' read-only headers.\n" + + "Wrong headers configuration for " + getComponentName()); } } + } - GatewayMethodInboundMessageMapper messageMapper = new GatewayMethodInboundMessageMapper(method, - headerExpressions, - this.globalMethodMetadata != null ? this.globalMethodMetadata.getHeaderExpressions() : null, - headers, this.argsMapper, this.getMessageBuilderFactory()); - if (StringUtils.hasText(payloadExpression)) { - messageMapper.setPayloadExpression(payloadExpression); - } - messageMapper.setBeanFactory(getBeanFactory()); - MethodInvocationGateway gateway = new MethodInvocationGateway(messageMapper); - - if (this.errorChannel != null) { - gateway.setErrorChannel(this.errorChannel); - } - else if (StringUtils.hasText(this.errorChannelName)) { - gateway.setErrorChannelName(this.errorChannelName); - } - - if (this.getTaskScheduler() != null) { - gateway.setTaskScheduler(this.getTaskScheduler()); - } - gateway.setBeanName(this.getComponentName()); - - if (StringUtils.hasText(requestChannelName)) { - gateway.setRequestChannelName(requestChannelName); - } - else if (StringUtils.hasText(this.defaultRequestChannelName)) { - gateway.setRequestChannelName(this.defaultRequestChannelName); - } - else { - gateway.setRequestChannel(this.defaultRequestChannel); - } - - if (StringUtils.hasText(replyChannelName)) { - gateway.setReplyChannelName(replyChannelName); - } - else if (StringUtils.hasText(this.defaultReplyChannelName)) { - gateway.setReplyChannelName(this.defaultReplyChannelName); - } - else { - gateway.setReplyChannel(this.defaultReplyChannel); - } - + private void timeouts(Expression requestTimeout, Expression replyTimeout, + GatewayMethodInboundMessageMapper messageMapper, MethodInvocationGateway gateway) { if (requestTimeout == null) { gateway.setRequestTimeout(-1); } @@ -733,15 +759,33 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint else { messageMapper.setReplyTimeoutExpression(replyTimeout); } - if (this.getBeanFactory() != null) { - gateway.setBeanFactory(this.getBeanFactory()); - } if (replyTimeout != null) { gateway.setReceiveTimeoutExpression(replyTimeout); } - gateway.setShouldTrack(this.shouldTrack); - gateway.afterPropertiesSet(); - return gateway; + } + + private void setChannel(MessageChannel channel, Consumer channelMethod, String channelName, + Consumer channelNameMethod) { + if (channel != null) { + channelMethod.accept(channel); + } + else if (StringUtils.hasText(channelName)) { + channelNameMethod.accept(channelName); + } + } + + private void setChannel(String channelName1, String channelName2, Consumer channelNameMethod, + MessageChannel channel, Consumer channelMethod) { + + if (StringUtils.hasText(channelName1)) { + channelNameMethod.accept(channelName1); + } + else if (StringUtils.hasText(channelName2)) { + channelNameMethod.accept(channelName2); + } + else { + channelMethod.accept(channel); + } } // Lifecycle implementation diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java index e8c8c6273e..a35c19eb0b 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java @@ -117,14 +117,8 @@ public class FileListFilterFactoryBean implements FactoryBean createdFilter = null; - if ((this.filter != null) && (this.filenamePattern != null || this.filenameRegex != null)) { - throw new IllegalArgumentException("The 'filter' reference is mutually exclusive with " - + "either the 'filename-pattern' or 'filename-regex' attribute."); - } - if (this.filenamePattern != null && this.filenameRegex != null) { - throw new IllegalArgumentException("The 'filename-pattern' and 'filename-regex' attributes are mutually exclusive."); - } + validate(); final List> filtersNeeded = new ArrayList>(); @@ -134,36 +128,12 @@ public class FileListFilterFactoryBean implements FactoryBean()); - filtersNeeded.add(this.filter); - } - else { // preventDuplicates is either FALSE or NULL - filtersNeeded.add(this.filter); - } + filter(filtersNeeded); } // 'file-pattern' or 'file-regex' is set else if (this.filenamePattern != null || this.filenameRegex != null) { - - if (!Boolean.FALSE.equals(this.preventDuplicates)) { - //preventDuplicates is either null or true - filtersNeeded.add(new AcceptOnceFileListFilter()); - } - if (this.filenamePattern != null) { - SimplePatternFileListFilter patternFilter = new SimplePatternFileListFilter(this.filenamePattern); - if (this.alwaysAcceptDirectories != null) { - patternFilter.setAlwaysAcceptDirectories(this.alwaysAcceptDirectories); - } - filtersNeeded.add(patternFilter); - } - if (this.filenameRegex != null) { - RegexPatternFileListFilter regexFilter = new RegexPatternFileListFilter(this.filenameRegex); - if (this.alwaysAcceptDirectories != null) { - regexFilter.setAlwaysAcceptDirectories(this.alwaysAcceptDirectories); - } - filtersNeeded.add(regexFilter); - } + pattern(filtersNeeded); } // no filters are provided @@ -184,4 +154,47 @@ public class FileListFilterFactoryBean implements FactoryBean> filtersNeeded) { + if (Boolean.TRUE.equals(this.preventDuplicates)) { + filtersNeeded.add(new AcceptOnceFileListFilter()); + filtersNeeded.add(this.filter); + } + else { // preventDuplicates is either FALSE or NULL + filtersNeeded.add(this.filter); + } + } + + private void pattern(final List> filtersNeeded) { + if (!Boolean.FALSE.equals(this.preventDuplicates)) { + //preventDuplicates is either null or true + filtersNeeded.add(new AcceptOnceFileListFilter()); + } + if (this.filenamePattern != null) { + SimplePatternFileListFilter patternFilter = new SimplePatternFileListFilter(this.filenamePattern); + if (this.alwaysAcceptDirectories != null) { + patternFilter.setAlwaysAcceptDirectories(this.alwaysAcceptDirectories); + } + filtersNeeded.add(patternFilter); + } + if (this.filenameRegex != null) { + RegexPatternFileListFilter regexFilter = new RegexPatternFileListFilter(this.filenameRegex); + if (this.alwaysAcceptDirectories != null) { + regexFilter.setAlwaysAcceptDirectories(this.alwaysAcceptDirectories); + } + filtersNeeded.add(regexFilter); + } + } + } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java index 6c3cc625d5..a2d55d7202 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java @@ -18,6 +18,7 @@ package org.springframework.integration.file.config; import java.io.File; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.ApplicationEventPublisher; @@ -27,6 +28,7 @@ import org.springframework.core.task.TaskExecutor; import org.springframework.integration.file.tail.ApacheCommonsFileTailingMessageProducer; import org.springframework.integration.file.tail.FileTailingMessageProducerSupport; import org.springframework.integration.file.tail.OSDelegatingFileTailingMessageProducer; +import org.springframework.integration.util.JavaUtils; import org.springframework.messaging.MessageChannel; import org.springframework.scheduling.TaskScheduler; import org.springframework.util.Assert; @@ -216,45 +218,27 @@ public class FileTailInboundChannelAdapterFactoryBean extends AbstractFactoryBea else { Assert.isTrue(this.nativeOptions == null, "'native-options' is not allowed with 'delay', 'end', or 'reopen'"); - adapter = new ApacheCommonsFileTailingMessageProducer(); - if (this.delay != null) { - ((ApacheCommonsFileTailingMessageProducer) adapter).setPollingDelay(this.delay); - } - if (this.end != null) { - ((ApacheCommonsFileTailingMessageProducer) adapter).setEnd(this.end); - } - if (this.reopen != null) { - ((ApacheCommonsFileTailingMessageProducer) adapter).setReopen(this.reopen); - } + ApacheCommonsFileTailingMessageProducer apache = new ApacheCommonsFileTailingMessageProducer(); + JavaUtils.INSTANCE + .acceptIfNotNull(this.delay, apache::setPollingDelay) + .acceptIfNotNull(this.end, apache::setEnd) + .acceptIfNotNull(this.reopen, apache::setReopen); + adapter = apache; } adapter.setFile(this.file); - if (this.taskExecutor != null) { - adapter.setTaskExecutor(this.taskExecutor); - } - if (this.taskScheduler != null) { - adapter.setTaskScheduler(this.taskScheduler); - } - if (this.fileDelay != null) { - adapter.setTailAttemptsDelay(this.fileDelay); - } - if (this.idleEventInterval != null) { - adapter.setIdleEventInterval(this.idleEventInterval); - } adapter.setOutputChannel(this.outputChannel); adapter.setErrorChannel(this.errorChannel); adapter.setBeanName(this.beanName); - if (this.autoStartup != null) { - adapter.setAutoStartup(this.autoStartup); - } - if (this.phase != null) { - adapter.setPhase(this.phase); - } - if (this.applicationEventPublisher != null) { - adapter.setApplicationEventPublisher(this.applicationEventPublisher); - } - if (getBeanFactory() != null) { - adapter.setBeanFactory(getBeanFactory()); // NOSONAR never null - } + BeanFactory beanFactory = getBeanFactory(); + JavaUtils.INSTANCE + .acceptIfNotNull(this.taskExecutor, adapter::setTaskExecutor) + .acceptIfNotNull(this.taskScheduler, adapter::setTaskScheduler) + .acceptIfNotNull(this.fileDelay, adapter::setTailAttemptsDelay) + .acceptIfNotNull(this.idleEventInterval, adapter::setIdleEventInterval) + .acceptIfNotNull(this.autoStartup, adapter::setAutoStartup) + .acceptIfNotNull(this.phase, adapter::setPhase) + .acceptIfNotNull(this.applicationEventPublisher, adapter::setApplicationEventPublisher) + .acceptIfNotNull(beanFactory, adapter::setBeanFactory); adapter.afterPropertiesSet(); this.tailAdapter = adapter; return adapter; diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java index c16cd3f556..efcf357def 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerBeanDefinitionBuilder.java @@ -77,6 +77,13 @@ abstract class FileWritingMessageHandlerBeanDefinitionBuilder { IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "flush-predicate"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "chmod"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "preserve-timestamp"); + filenameGenerators(element, parserContext, builder); + return builder; + } + + private static void filenameGenerators(Element element, ParserContext parserContext, + BeanDefinitionBuilder builder) { + String remoteFileNameGenerator = element.getAttribute("filename-generator"); String remoteFileNameGeneratorExpression = element.getAttribute("filename-generator-expression"); boolean hasRemoteFileNameGenerator = StringUtils.hasText(remoteFileNameGenerator); @@ -97,7 +104,6 @@ abstract class FileWritingMessageHandlerBeanDefinitionBuilder { builder.addPropertyValue("fileNameGenerator", fileNameGeneratorBuilder.getBeanDefinition()); } } - return builder; } } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerFactoryBean.java index 0f3027c75c..e1210aeeda 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileWritingMessageHandlerFactoryBean.java @@ -24,6 +24,7 @@ import org.springframework.integration.file.FileNameGenerator; import org.springframework.integration.file.FileWritingMessageHandler; import org.springframework.integration.file.FileWritingMessageHandler.MessageFlushPredicate; import org.springframework.integration.file.support.FileExistsMode; +import org.springframework.integration.util.JavaUtils; /** * Factory bean used to create {@link FileWritingMessageHandler}s. @@ -167,52 +168,23 @@ public class FileWritingMessageHandlerFactoryBean throw new IllegalStateException("Either directory or directoryExpression must not be null"); } - if (this.charset != null) { - handler.setCharset(this.charset); - } - if (this.fileNameGenerator != null) { - handler.setFileNameGenerator(this.fileNameGenerator); - } - if (this.deleteSourceFiles != null) { - handler.setDeleteSourceFiles(this.deleteSourceFiles); - } - if (this.autoCreateDirectory != null) { - handler.setAutoCreateDirectory(this.autoCreateDirectory); - } - if (this.requiresReply != null) { - handler.setRequiresReply(this.requiresReply); - } - if (this.sendTimeout != null) { - handler.setSendTimeout(this.sendTimeout); - } - if (this.temporaryFileSuffix != null) { - handler.setTemporaryFileSuffix(this.temporaryFileSuffix); - } handler.setExpectReply(this.expectReply); - if (this.appendNewLine != null) { - handler.setAppendNewLine(this.appendNewLine); - } - if (this.fileExistsMode != null) { - handler.setFileExistsMode(this.fileExistsMode); - } - if (this.bufferSize != null) { - handler.setBufferSize(this.bufferSize); - } - if (this.flushInterval != null) { - handler.setFlushInterval(this.flushInterval); - } - if (this.flushWhenIdle != null) { - handler.setFlushWhenIdle(this.flushWhenIdle); - } - if (this.flushPredicate != null) { - handler.setFlushPredicate(this.flushPredicate); - } - if (this.chmod != null) { - handler.setChmodOctal(this.chmod); - } - if (this.preserveTimestamp != null) { - handler.setPreserveTimestamp(this.preserveTimestamp); - } + JavaUtils.INSTANCE + .acceptIfNotNull(this.charset, handler::setCharset) + .acceptIfNotNull(this.fileNameGenerator, handler::setFileNameGenerator) + .acceptIfNotNull(this.deleteSourceFiles, handler::setDeleteSourceFiles) + .acceptIfNotNull(this.autoCreateDirectory, handler::setAutoCreateDirectory) + .acceptIfNotNull(this.requiresReply, handler::setRequiresReply) + .acceptIfNotNull(this.sendTimeout, handler::setSendTimeout) + .acceptIfNotNull(this.temporaryFileSuffix, handler::setTemporaryFileSuffix) + .acceptIfNotNull(this.appendNewLine, handler::setAppendNewLine) + .acceptIfNotNull(this.fileExistsMode, handler::setFileExistsMode) + .acceptIfNotNull(this.bufferSize, handler::setBufferSize) + .acceptIfNotNull(this.flushInterval, handler::setFlushInterval) + .acceptIfNotNull(this.flushWhenIdle, handler::setFlushWhenIdle) + .acceptIfNotNull(this.flushPredicate, handler::setFlushPredicate) + .acceptIfNotNull(this.chmod, handler::setChmodOctal) + .acceptIfNotNull(this.preserveTimestamp, handler::setPreserveTimestamp); return handler; } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/RemoteFileTemplate.java b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/RemoteFileTemplate.java index 38e53b0ba4..25cfa60c0b 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/RemoteFileTemplate.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/RemoteFileTemplate.java @@ -301,7 +301,7 @@ public class RemoteFileTemplate implements RemoteFileOperations, Initializ try { inputStreamHolder.stream.close(); } - catch (IOException e) { + catch (@SuppressWarnings("unused") IOException e) { } } } @@ -544,47 +544,52 @@ public class RemoteFileTemplate implements RemoteFileOperations, Initializ try { RemoteFileUtils.makeDirectories(remoteDirectory, session, this.remoteFileSeparator, this.logger); } - catch (IllegalStateException e) { + catch (@SuppressWarnings("unused") IllegalStateException e) { // Revert to old FTP behavior if recursive mkdir fails, for backwards compatibility session.mkdir(remoteDirectory); } } try (InputStream stream = inputStream) { - boolean rename = this.useTemporaryFileName; - if (FileExistsMode.REPLACE.equals(mode)) { - session.write(stream, tempFilePath); - } - else if (FileExistsMode.APPEND.equals(mode)) { - session.append(stream, tempFilePath); - } - else { - if (exists(remoteFilePath)) { - if (FileExistsMode.FAIL.equals(mode)) { - throw new MessagingException( - "The destination file already exists at '" + remoteFilePath + "'."); - } - else { - if (this.logger.isDebugEnabled()) { - this.logger.debug("File not transferred to '" + remoteFilePath + "'; already exists."); - } - } - rename = false; - } - else { - session.write(stream, tempFilePath); - } - } - // then rename it to its final name if necessary - if (rename) { - session.rename(tempFilePath, remoteFilePath); - } + doSend(session, mode, remoteFilePath, tempFilePath, stream); } catch (Exception e) { throw new MessagingException("Failed to write to '" + tempFilePath + "' while uploading the file", e); } } + private void doSend(Session session, FileExistsMode mode, String remoteFilePath, String tempFilePath, + InputStream stream) throws IOException { + boolean rename = this.useTemporaryFileName; + if (FileExistsMode.REPLACE.equals(mode)) { + session.write(stream, tempFilePath); + } + else if (FileExistsMode.APPEND.equals(mode)) { + session.append(stream, tempFilePath); + } + else { + if (exists(remoteFilePath)) { + if (FileExistsMode.FAIL.equals(mode)) { + throw new MessagingException( + "The destination file already exists at '" + remoteFilePath + "'."); + } + else { + if (this.logger.isDebugEnabled()) { + this.logger.debug("File not transferred to '" + remoteFilePath + "'; already exists."); + } + } + rename = false; + } + else { + session.write(stream, tempFilePath); + } + } + // then rename it to its final name if necessary + if (rename) { + session.rename(tempFilePath, remoteFilePath); + } + } + private String normalizeDirectoryPath(String directoryPath) { if (!StringUtils.hasText(directoryPath)) { return ""; diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java index 42da06389f..fbdf7a395c 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java @@ -758,19 +758,25 @@ public abstract class AbstractRemoteFileOutboundGateway extends AbstractReply } } } - catch (Exception ex) { - if (replies.size() > 0 || ex instanceof PartialSuccessException) { // NOSONAR - throw new PartialSuccessException(requestMessage, - "Partially successful 'mput' operation" + - (subDirectory == null ? "" : (" on " + subDirectory)), ex, replies, filteredFiles); - } - else { - throw ex; - } + catch (RuntimeException ex) { + throw handlePutException(requestMessage, subDirectory, filteredFiles, replies, ex); } return replies; } + private RuntimeException handlePutException(Message requestMessage, String subDirectory, + List filteredFiles, List replies, RuntimeException ex) { + + if (replies.size() > 0 || ex instanceof PartialSuccessException) { + return new PartialSuccessException(requestMessage, + "Partially successful 'mput' operation" + + (subDirectory == null ? "" : (" on " + subDirectory)), ex, replies, filteredFiles); + } + else { + return ex; + } + } + /** * List remote files to local representation. * The message can be consulted for some context for the current request; @@ -889,8 +895,9 @@ public abstract class AbstractRemoteFileOutboundGateway extends AbstractReply * @return The file. * @throws IOException Any IOException. */ - protected File get(Message message, Session session, String remoteDir, String remoteFilePath, - String remoteFilename, F fileInfoParam) throws IOException { + protected File get(Message message, Session session, String remoteDir, // NOSONAR complexity + String remoteFilePath, String remoteFilename, F fileInfoParam) throws IOException { + F fileInfo = fileInfoParam; if (fileInfo == null) { F[] files = session.list(remoteFilePath); diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/splitter/FileSplitter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/splitter/FileSplitter.java index 8ecea9c54b..a9cff1673a 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/splitter/FileSplitter.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/splitter/FileSplitter.java @@ -166,7 +166,7 @@ public class FileSplitter extends AbstractMessageSplitter { this.firstLineHeaderName = firstLineHeaderName; } - @Override + @Override// NOSONAR complexity protected Object splitMessage(final Message message) { Object payload = message.getPayload(); diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java index a882651998..50bbcc85a1 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java @@ -24,6 +24,7 @@ import javax.net.ssl.TrustManager; import org.apache.commons.net.ftp.FTPSClient; +import org.springframework.integration.util.JavaUtils; import org.springframework.util.StringUtils; /** @@ -141,37 +142,18 @@ public class DefaultFtpsSessionFactory extends AbstractFtpSessionFactory { @Override public String getPermissions() { StringBuilder sb = new StringBuilder(); - if (this.ftpFile.isDirectory()) { - sb.append("d"); - } - else if (this.ftpFile.isSymbolicLink()) { - sb.append("l"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION)) { - sb.append("r"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION)) { - sb.append("w"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION)) { - sb.append("x"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION)) { - sb.append("r"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION)) { - sb.append("w"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION)) { - sb.append("x"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION)) { - sb.append("r"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION)) { - sb.append("w"); - } - else { - sb.append("-"); - } - if (this.ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION)) { - sb.append("x"); - } - else { - sb.append("-"); - } + appendPermissionString(sb, this.ftpFile.isDirectory(), 'd', this.ftpFile.isSymbolicLink(), 'l'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION), 'r'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION), 'w'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION), 'x'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION), 'r'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION), 'w'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION), 'x'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION), 'r'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION), 'w'); + appendPermissionString(sb, this.ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION), 'x'); return sb.toString(); } + private void appendPermissionString(StringBuilder sb, boolean condition1, char char1, boolean condition2, + char char2) { + + if (condition1) { + sb.append(char1); + } + else if (condition2) { + sb.append(char2); + } + else { + sb.append('-'); + } + } + + private void appendPermissionString(StringBuilder sb, boolean condition, char char1) { + if (condition) { + sb.append(char1); + } + else { + sb.append('-'); + } + } + @Override public FTPFile getFileInfo() { return this.ftpFile;