/** * Builds and configures a {@link BeanDefinitionBuilder} for {@link * HdfsStoreMessageHandlerFactoryBean}. * * @param element The element. * @param parserContext The parser context. * @return The bean definition builder */ static BeanDefinitionBuilder configure(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(HdfsStoreMessageHandlerFactoryBean.class); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "writer", "storeWriter"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup"); return builder; }
@Override protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( "org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler"); builder.addConstructorArgValue(element.getAttribute("url")); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "http-method"); String restTemplate = element.getAttribute("rest-template"); if (StringUtils.hasText(restTemplate)) { HttpAdapterParsingUtils.verifyNoRestTemplateAttributes(element, parserContext); builder.addConstructorArgReference(restTemplate); } else { for (String referenceAttributeName : HttpAdapterParsingUtils.REST_TEMPLATE_REFERENCE_ATTRIBUTES) { IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, referenceAttributeName); } } String headerMapper = element.getAttribute("header-mapper"); String mappedRequestHeaders = element.getAttribute("mapped-request-headers"); String mappedResponseHeaders = element.getAttribute("mapped-response-headers"); if (StringUtils.hasText(headerMapper)) { if (StringUtils.hasText(mappedRequestHeaders) || StringUtils.hasText(mappedResponseHeaders)) { parserContext .getReaderContext() .error( "Neither 'mappped-request-headers' or 'mapped-response-headers' " + "attributes are allowed when a 'header-mapper' has been specified.", parserContext.extractSource(element)); return null; } builder.addPropertyReference("headerMapper", headerMapper); } else { BeanDefinitionBuilder headerMapperBuilder = BeanDefinitionBuilder.genericBeanDefinition( "org.springframework.integration.http.support.DefaultHttpHeaderMapper"); headerMapperBuilder.setFactoryMethod("outboundMapper"); IntegrationNamespaceUtils.setValueIfAttributeDefined( headerMapperBuilder, element, "mapped-request-headers", "outboundHeaderNames"); IntegrationNamespaceUtils.setValueIfAttributeDefined( headerMapperBuilder, element, "mapped-response-headers", "inboundHeaderNames"); builder.addPropertyValue("headerMapper", headerMapperBuilder.getBeanDefinition()); } IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset"); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "extract-request-payload", "extractPayload"); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "expected-response-type"); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "reply-timeout", "sendTimeout"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "reply-channel", "outputChannel"); HttpAdapterParsingUtils.configureUriVariableExpressions(builder, element); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "transfer-cookies"); return builder; }
/** * Create a new {@link BeanDefinitionBuilder} for the class {@link StoredProcExecutor}. Initialize * the wrapped {@link StoredProcExecutor} with common properties. * * @param element Must not be Null * @param parserContext Must not be Null * @return The {@link BeanDefinitionBuilder} for the {@link StoredProcExecutor} */ public static BeanDefinitionBuilder getStoredProcExecutorBuilder( final Element element, final ParserContext parserContext) { Assert.notNull(element, "The provided element must not be Null."); Assert.notNull(parserContext, "The provided parserContext must not be Null."); final String dataSourceRef = element.getAttribute("data-source"); final BeanDefinitionBuilder storedProcExecutorBuilder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcExecutor.class); storedProcExecutorBuilder.addConstructorArgReference(dataSourceRef); final String storedProcedureName = element.getAttribute("stored-procedure-name"); final String storedProcedureNameExpression = element.getAttribute("stored-procedure-name-expression"); boolean hasStoredProcedureName = StringUtils.hasText(storedProcedureName); boolean hasStoredProcedureNameExpression = StringUtils.hasText(storedProcedureNameExpression); if (!(hasStoredProcedureName ^ hasStoredProcedureNameExpression)) { parserContext .getReaderContext() .error( "Exactly one of 'stored-procedure-name' or 'stored-procedure-name-expression' is required", element); } BeanDefinitionBuilder expressionBuilder; if (hasStoredProcedureNameExpression) { expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class); expressionBuilder.addConstructorArgValue(storedProcedureNameExpression); } else { expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(LiteralExpression.class); expressionBuilder.addConstructorArgValue(storedProcedureName); } storedProcExecutorBuilder.addPropertyValue( "storedProcedureNameExpression", expressionBuilder.getBeanDefinition()); IntegrationNamespaceUtils.setValueIfAttributeDefined( storedProcExecutorBuilder, element, "ignore-column-meta-data"); IntegrationNamespaceUtils.setValueIfAttributeDefined( storedProcExecutorBuilder, element, "jdbc-call-operations-cache-size"); final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(element, parserContext); final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(element, parserContext); if (!procedureParameterList.isEmpty()) { storedProcExecutorBuilder.addPropertyValue("procedureParameters", procedureParameterList); } if (!sqlParameterDefinitionList.isEmpty()) { storedProcExecutorBuilder.addPropertyValue("sqlParameters", sqlParameterDefinitionList); } return storedProcExecutorBuilder; }
@Override protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { final BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ContentEnricher.class); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-channel"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply"); List<Element> subElements = DomUtils.getChildElementsByTagName(element, "property"); if (!CollectionUtils.isEmpty(subElements)) { ManagedMap<String, Object> expressions = new ManagedMap<String, Object>(); for (Element subElement : subElements) { String name = subElement.getAttribute("name"); BeanDefinition beanDefinition = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( "value", "expression", parserContext, subElement, true); expressions.put(name, beanDefinition); } builder.addPropertyValue("propertyExpressions", expressions); } subElements = DomUtils.getChildElementsByTagName(element, "header"); if (!CollectionUtils.isEmpty(subElements)) { ManagedMap<String, Object> expressions = new ManagedMap<String, Object>(); for (Element subElement : subElements) { String name = subElement.getAttribute("name"); BeanDefinition expressionDefinition = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( "value", "expression", parserContext, subElement, true); BeanDefinitionBuilder valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition( IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.support.ExpressionEvaluatingHeaderValueMessageProcessor"); valueProcessorBuilder .addConstructorArgValue(expressionDefinition) .addConstructorArgValue(subElement.getAttribute("type")); IntegrationNamespaceUtils.setValueIfAttributeDefined( valueProcessorBuilder, subElement, "overwrite"); expressions.put(name, valueProcessorBuilder.getBeanDefinition()); } builder.addPropertyValue("headerExpressions", expressions); } IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "should-clone-payload"); String requestPayloadExpression = element.getAttribute("request-payload-expression"); if (StringUtils.hasText(requestPayloadExpression)) { BeanDefinitionBuilder expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class); expressionBuilder.addConstructorArgValue(requestPayloadExpression); builder.addPropertyValue("requestPayloadExpression", expressionBuilder.getBeanDefinition()); } return builder; }
private void configureRequestHandlerAdviceChain( Element element, ParserContext parserContext, BeanDefinition handlerBeanDefinition, BeanDefinitionBuilder consumerBuilder) { Element adviceChainElement = DomUtils.getChildElementByTagName( element, IntegrationNamespaceUtils.REQUEST_HANDLER_ADVICE_CHAIN); @SuppressWarnings("rawtypes") ManagedList adviceChain = IntegrationNamespaceUtils.configureAdviceChain( adviceChainElement, null, handlerBeanDefinition, parserContext); if (adviceChain != null) { /* * For ARPMH, the advice chain is injected so just the handleRequestMessage method is advised. * Sometime ARPMHs do double duty as a gateway and a channel adapter. The parser subclass * can indicate this by overriding isUsingReplyProducer(), or we can try to determine it from * the bean class. */ boolean isReplyProducer = this.isUsingReplyProducer(); if (!isReplyProducer) { Class<?> beanClass = null; if (handlerBeanDefinition instanceof AbstractBeanDefinition) { AbstractBeanDefinition abstractBeanDefinition = (AbstractBeanDefinition) handlerBeanDefinition; if (abstractBeanDefinition.hasBeanClass()) { beanClass = abstractBeanDefinition.getBeanClass(); } } isReplyProducer = beanClass != null && AbstractReplyProducingMessageHandler.class.isAssignableFrom(beanClass); } if (isReplyProducer) { handlerBeanDefinition.getPropertyValues().add("adviceChain", adviceChain); } else if (consumerBuilder != null) { consumerBuilder.addPropertyValue("adviceChain", adviceChain); } else { String elementDescription = IntegrationNamespaceUtils.createElementDescription(element); parserContext .getReaderContext() .error( "'request-handler-advice-chain' isn't allowed for " + elementDescription + " within a <chain/>, because its Handler " + "isn't an AbstractReplyProducingMessageHandler", element); } } }
@Override protected AbstractBeanDefinition doParse( Element element, ParserContext parserContext, String channelName) { BeanDefinitionBuilder builder = ReactorNamespaceUtils.createBeanDefinitionBuilder( SyslogInboundChannelAdapter.class, element); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "host", "host"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "port", "port"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "channel", "outputChannel"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "error-channel", "errorChannel"); return builder.getBeanDefinition(); }
@Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RedisCollectionPopulatingMessageHandler.class); String redisTemplateRef = element.getAttribute("redis-template"); String connectionFactory = element.getAttribute("connection-factory"); if (StringUtils.hasText(redisTemplateRef) && StringUtils.hasText(connectionFactory)) { parserContext .getReaderContext() .error("Only one of 'redis-template' or 'connection-factory'" + " is allowed", element); } if (StringUtils.hasText(redisTemplateRef)) { builder.addConstructorArgReference(redisTemplateRef); } else { if (!StringUtils.hasText(connectionFactory)) { connectionFactory = "redisConnectionFactory"; } builder.addConstructorArgReference(connectionFactory); } boolean atLeastOneRequired = false; RootBeanDefinition expressionDef = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( "key", "key-expression", parserContext, element, atLeastOneRequired); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "collection-type"); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "extract-payload-elements"); if (expressionDef != null) { builder.addConstructorArgValue(expressionDef); } String mapKeyExpression = element.getAttribute("map-key-expression"); if (StringUtils.hasText(mapKeyExpression)) { RootBeanDefinition mapKeyExpressionDef = new RootBeanDefinition(ExpressionFactoryBean.class); mapKeyExpressionDef.getConstructorArgumentValues().addGenericArgumentValue(mapKeyExpression); builder.addPropertyValue("mapKeyExpression", mapKeyExpressionDef); } return builder.getBeanDefinition(); }
@Override protected AbstractBeanDefinition doParse( Element element, ParserContext parserContext, String channelName) { if (parserContext.isNested()) { if (channelName != null) { String elementDescription = IntegrationNamespaceUtils.createElementDescription(element); parserContext .getReaderContext() .error( "The 'channel' attribute isn't allowed for " + elementDescription + " when it is used as a nested element," + " e.g. inside a <chain/>", element); } AbstractBeanDefinition consumerBeanDefinition = this.parseConsumer(element, parserContext); this.configureRequestHandlerAdviceChain(element, parserContext, consumerBeanDefinition, null); return consumerBeanDefinition; } BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerEndpointFactoryBean.class); Element pollerElement = DomUtils.getChildElementByTagName(element, "poller"); BeanComponentDefinition handlerBeanComponentDefinition = this.doParseAndRegisterConsumer(element, parserContext); builder.addPropertyReference("handler", handlerBeanComponentDefinition.getBeanName()); IntegrationNamespaceUtils.checkAndConfigureFixedSubscriberChannel( element, parserContext, channelName, handlerBeanComponentDefinition.getBeanName()); if (pollerElement != null) { if (!StringUtils.hasText(channelName)) { parserContext .getReaderContext() .error( "outbound channel adapter with a 'poller' requires a 'channel' to poll", element); } IntegrationNamespaceUtils.configurePollerMetadata(pollerElement, builder, parserContext); } builder.addPropertyValue("inputChannelName", channelName); this.configureRequestHandlerAdviceChain( element, parserContext, handlerBeanComponentDefinition.getBeanDefinition(), builder); return builder.getBeanDefinition(); }
@Override protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcPollingChannelAdapter.class); final BeanDefinitionBuilder storedProcExecutorBuilder = StoredProcParserUtils.getStoredProcExecutorBuilder(element, parserContext); IntegrationNamespaceUtils.setValueIfAttributeDefined( storedProcExecutorBuilder, element, "return-value-required"); IntegrationNamespaceUtils.setValueIfAttributeDefined( storedProcExecutorBuilder, element, "function"); IntegrationNamespaceUtils.setValueIfAttributeDefined( storedProcExecutorBuilder, element, "skip-undeclared-results"); final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext); if (!returningResultsetMap.isEmpty()) { storedProcExecutorBuilder.addPropertyValue( "returningResultSetRowMappers", returningResultsetMap); } final AbstractBeanDefinition storedProcExecutorBuilderBeanDefinition = storedProcExecutorBuilder.getBeanDefinition(); final String storedProcPollingChannelAdapterId = this.resolveId(element, builder.getRawBeanDefinition(), parserContext); final String storedProcExecutorBeanName = storedProcPollingChannelAdapterId + ".storedProcExecutor"; parserContext.registerBeanComponent( new BeanComponentDefinition( storedProcExecutorBuilderBeanDefinition, storedProcExecutorBeanName)); builder.addConstructorArgReference(storedProcExecutorBeanName); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result"); return builder.getBeanDefinition(); }
@Override protected AbstractBeanDefinition doParse( Element element, ParserContext parserContext, String channelName) { BeanMetadataElement source = this.parseSource(element, parserContext); if (source == null) { parserContext.getReaderContext().error("failed to parse source", element); } BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SourcePollingChannelAdapterFactoryBean.class); adapterBuilder.addPropertyValue("source", source); adapterBuilder.addPropertyReference("outputChannel", channelName); IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "send-timeout"); Element pollerElement = DomUtils.getChildElementByTagName(element, "poller"); if (pollerElement != null) { IntegrationNamespaceUtils.configurePollerMetadata( pollerElement, adapterBuilder, parserContext); } IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "auto-startup"); IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "phase"); return adapterBuilder.getBeanDefinition(); }
@Override protected BeanDefinitionBuilder buildBeanDefinition( Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SubscribableRedisChannel.class); String connectionFactory = element.getAttribute("connection-factory"); if (!StringUtils.hasText(connectionFactory)) { connectionFactory = "redisConnectionFactory"; } builder.addConstructorArgReference(connectionFactory); String topicName = element.getAttribute("topic-name"); builder.addConstructorArgValue(topicName); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "task-executor"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converter"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "serializer"); // The following 2 attributes should be added once configurable on the // RedisMessageListenerContainer // IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "phase"); // IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup"); return builder; }
@Override protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) { final BeanDefinitionBuilder jpaPollingChannelAdapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(JpaPollingChannelAdapter.class); final BeanDefinitionBuilder jpaExecutorBuilder = JpaParserUtils.getJpaExecutorBuilder(element, parserContext); String maxNumberOfResults = element.getAttribute("max-number-of-results"); boolean hasMaxNumberOfResults = StringUtils.hasText(maxNumberOfResults); String maxResults = element.getAttribute("max-results"); boolean hasMaxResults = StringUtils.hasText(maxResults); if (hasMaxNumberOfResults) { parserContext .getReaderContext() .warning("'max-number-of-results' is deprecated in favor of 'max-results'", element); if (hasMaxResults) { parserContext .getReaderContext() .error("'max-number-of-results' and 'max-results' are mutually exclusive", element); } else { element.setAttribute("max-results", maxNumberOfResults); } } BeanDefinition definition = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( "max-results", "max-results-expression", parserContext, element, false); if (definition != null) { jpaExecutorBuilder.addPropertyValue("maxResultsExpression", definition); } IntegrationNamespaceUtils.setValueIfAttributeDefined( jpaExecutorBuilder, element, "delete-after-poll"); IntegrationNamespaceUtils.setValueIfAttributeDefined( jpaExecutorBuilder, element, "flush-after-delete", "flush"); IntegrationNamespaceUtils.setValueIfAttributeDefined( jpaExecutorBuilder, element, "delete-in-batch"); IntegrationNamespaceUtils.setValueIfAttributeDefined( jpaExecutorBuilder, element, "expect-single-result"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( jpaExecutorBuilder, element, "parameter-source"); final BeanDefinition jpaExecutorBuilderBeanDefinition = jpaExecutorBuilder.getBeanDefinition(); final String channelAdapterId = this.resolveId( element, jpaPollingChannelAdapterBuilder.getRawBeanDefinition(), parserContext); final String jpaExecutorBeanName = channelAdapterId + ".jpaExecutor"; parserContext.registerBeanComponent( new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); jpaPollingChannelAdapterBuilder.addConstructorArgReference(jpaExecutorBeanName); return jpaPollingChannelAdapterBuilder.getBeanDefinition(); }
@SuppressWarnings({"rawtypes", "unchecked"}) public static ManagedList configureAdviceChain( Element adviceChainElement, Element txElement, BeanDefinition parentBeanDefinition, ParserContext parserContext) { ManagedList adviceChain = null; // Schema validation ensures txElement and adviceChainElement are mutually exclusive if (txElement != null) { adviceChain = new ManagedList(); adviceChain.add(IntegrationNamespaceUtils.configureTransactionAttributes(txElement)); } if (adviceChainElement != null) { adviceChain = new ManagedList(); NodeList childNodes = adviceChainElement.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { Element childElement = (Element) child; String localName = child.getLocalName(); if ("bean".equals(localName)) { BeanDefinitionHolder holder = parserContext .getDelegate() .parseBeanDefinitionElement(childElement, parentBeanDefinition); parserContext.registerBeanComponent(new BeanComponentDefinition(holder)); adviceChain.add(new RuntimeBeanReference(holder.getBeanName())); } else if ("ref".equals(localName)) { String ref = childElement.getAttribute("bean"); adviceChain.add(new RuntimeBeanReference(ref)); } else { BeanDefinition customBeanDefinition = parserContext.getDelegate().parseCustomElement(childElement, parentBeanDefinition); if (customBeanDefinition == null) { parserContext .getReaderContext() .error("failed to parse custom element '" + localName + "'", childElement); } adviceChain.add(customBeanDefinition); } } } } return adviceChain; }
@Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RequestHandlerRetryAdvice.class); BeanDefinitionBuilder retryTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(RetryTemplate.class); boolean customTemplate = false; Element backOffPolicyEle = DomUtils.getChildElementByTagName(element, "fixed-back-off"); BeanDefinitionBuilder backOffBuilder = null; if (backOffPolicyEle != null) { backOffBuilder = BeanDefinitionBuilder.genericBeanDefinition(FixedBackOffPolicy.class); IntegrationNamespaceUtils.setValueIfAttributeDefined( backOffBuilder, backOffPolicyEle, "interval", "backOffPeriod"); } else { backOffPolicyEle = DomUtils.getChildElementByTagName(element, "exponential-back-off"); if (backOffPolicyEle != null) { backOffBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExponentialBackOffPolicy.class); IntegrationNamespaceUtils.setValueIfAttributeDefined( backOffBuilder, backOffPolicyEle, "initial", "initialInterval"); IntegrationNamespaceUtils.setValueIfAttributeDefined( backOffBuilder, backOffPolicyEle, "multiplier"); IntegrationNamespaceUtils.setValueIfAttributeDefined( backOffBuilder, backOffPolicyEle, "maximum", "maxInterval"); } } if (backOffBuilder != null) { retryTemplateBuilder.addPropertyValue("backOffPolicy", backOffBuilder.getBeanDefinition()); customTemplate = true; } String maxAttemptsAttr = element.getAttribute("max-attempts"); if (StringUtils.hasText(maxAttemptsAttr)) { BeanDefinitionBuilder retryPolicyBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleRetryPolicy.class); IntegrationNamespaceUtils.setValueIfAttributeDefined( retryPolicyBuilder, element, "max-attempts"); retryTemplateBuilder.addPropertyValue("retryPolicy", retryPolicyBuilder.getBeanDefinition()); customTemplate = true; } if (customTemplate) { builder.addPropertyValue("retryTemplate", retryTemplateBuilder.getBeanDefinition()); } String recoveryChannelAttr = element.getAttribute("recovery-channel"); if (StringUtils.hasText(recoveryChannelAttr)) { BeanDefinitionBuilder emsrBuilder = BeanDefinitionBuilder.genericBeanDefinition(ErrorMessageSendingRecoverer.class); emsrBuilder.addConstructorArgReference(recoveryChannelAttr); IntegrationNamespaceUtils.setValueIfAttributeDefined(emsrBuilder, element, "send-timeout"); builder.addPropertyValue("recoveryCallback", emsrBuilder.getBeanDefinition()); } return builder.getBeanDefinition(); }
/** Utility method to configure HeaderMapper for Inbound and Outbound channel adapters/gateway */ public static void configureHeaderMapper( Element element, BeanDefinitionBuilder rootBuilder, ParserContext parserContext, Class<?> headerMapperClass, String replyHeaderValue) { String defaultMappedReplyHeadersAttributeName = "mapped-reply-headers"; if (!StringUtils.hasText(replyHeaderValue)) { replyHeaderValue = defaultMappedReplyHeadersAttributeName; } boolean hasHeaderMapper = element.hasAttribute("header-mapper"); boolean hasMappedRequestHeaders = element.hasAttribute("mapped-request-headers"); boolean hasMappedReplyHeaders = element.hasAttribute(replyHeaderValue); if (hasHeaderMapper && (hasMappedRequestHeaders || hasMappedReplyHeaders)) { parserContext .getReaderContext() .error( "The 'header-mapper' attribute is mutually exclusive with" + " 'mapped-request-headers' or 'mapped-reply-headers'. " + "You can only use one or the others", element); } IntegrationNamespaceUtils.setReferenceIfAttributeDefined(rootBuilder, element, "header-mapper"); if (hasMappedRequestHeaders || hasMappedReplyHeaders) { BeanDefinitionBuilder headerMapperBuilder = BeanDefinitionBuilder.genericBeanDefinition(headerMapperClass); if (hasMappedRequestHeaders) { headerMapperBuilder.addPropertyValue( "requestHeaderNames", element.getAttribute("mapped-request-headers")); } if (hasMappedReplyHeaders) { headerMapperBuilder.addPropertyValue( "replyHeaderNames", element.getAttribute(replyHeaderValue)); } rootBuilder.addPropertyValue("headerMapper", headerMapperBuilder.getBeanDefinition()); } }
/** * Override this method to control the registration process and return the bean name. If parsing a * bean definition whose name can be auto-generated, consider using {@link #parseConsumer(Element, * ParserContext)} instead. * * @param element The element. * @param parserContext The parser context. * @return The bean component definition. */ protected BeanComponentDefinition doParseAndRegisterConsumer( Element element, ParserContext parserContext) { AbstractBeanDefinition definition = this.parseConsumer(element, parserContext); if (definition == null) { parserContext .getReaderContext() .error("Consumer parsing must return an AbstractBeanDefinition.", element); } String order = element.getAttribute(IntegrationNamespaceUtils.ORDER); if (StringUtils.hasText(order)) { definition.getPropertyValues().addPropertyValue(IntegrationNamespaceUtils.ORDER, order); } String beanName = BeanDefinitionReaderUtils.generateBeanName(definition, parserContext.getRegistry()); String[] handlerAlias = IntegrationNamespaceUtils.generateAlias(element); BeanComponentDefinition beanComponentDefinition = new BeanComponentDefinition(definition, beanName, handlerAlias); parserContext.registerBeanComponent(beanComponentDefinition); return beanComponentDefinition; }
@Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder metadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(PollerMetadata.class); if (element.hasAttribute("ref")) { parserContext .getReaderContext() .error( "the 'ref' attribute must not be present on the top-level 'poller' element", element); } configureTrigger(element, metadataBuilder, parserContext); IntegrationNamespaceUtils.setValueIfAttributeDefined( metadataBuilder, element, "max-messages-per-poll"); IntegrationNamespaceUtils.setValueIfAttributeDefined( metadataBuilder, element, "receive-timeout"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( metadataBuilder, element, "task-executor"); Element txElement = DomUtils.getChildElementByTagName(element, "transactional"); Element adviceChainElement = DomUtils.getChildElementByTagName(element, "advice-chain"); IntegrationNamespaceUtils.configureAndSetAdviceChainIfPresent( adviceChainElement, txElement, metadataBuilder.getRawBeanDefinition(), parserContext); if (txElement != null) { IntegrationNamespaceUtils.setReferenceIfAttributeDefined( metadataBuilder, txElement, "synchronization-factory", "transactionSynchronizationFactory"); } else if (adviceChainElement != null) { IntegrationNamespaceUtils.setReferenceIfAttributeDefined( metadataBuilder, adviceChainElement, "synchronization-factory", "transactionSynchronizationFactory"); } String errorChannel = element.getAttribute("error-channel"); if (StringUtils.hasText(errorChannel)) { BeanDefinitionBuilder errorHandler = BeanDefinitionBuilder.genericBeanDefinition(MessagePublishingErrorHandler.class); errorHandler.addPropertyReference("defaultErrorChannel", errorChannel); metadataBuilder.addPropertyValue("errorHandler", errorHandler.getBeanDefinition()); } return metadataBuilder.getBeanDefinition(); }
@Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(AmqpOutboundEndpoint.class); String amqpTemplateRef = element.getAttribute("amqp-template"); if (!StringUtils.hasText(amqpTemplateRef)) { amqpTemplateRef = "amqpTemplate"; } builder.addConstructorArgReference(amqpTemplateRef); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "exchange-name", true); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "exchange-name-expression"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "routing-key", true); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "routing-key-expression"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "default-delivery-mode"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "lazy-connect"); IntegrationNamespaceUtils.configureHeaderMapper( element, builder, parserContext, DefaultAmqpHeaderMapper.class, null); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "confirm-correlation-expression"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "confirm-ack-channel"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "confirm-nack-channel"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "return-channel"); return builder.getBeanDefinition(); }
@Override protected void doParse( Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { builder.addConstructorArgValue(this.expectReply); String inputChannelAttributeName = this.getInputChannelAttributeName(); String inputChannelRef = element.getAttribute(inputChannelAttributeName); if (!StringUtils.hasText(inputChannelRef)) { parserContext .getReaderContext() .error("a '" + inputChannelAttributeName + "' reference is required", element); } builder.addPropertyReference("requestChannel", inputChannelRef); if (this.expectReply) { IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "extract-reply-payload"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-key"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "convert-exceptions"); } else { IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "send-timeout", "requestTimeout"); } IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "supported-methods", "supportedMethodNames"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-payload-type"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "view-name"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "errors-key"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "error-code"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "message-converters"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "header-mapper"); }
@Override protected BeanDefinitionBuilder buildBeanDefinition( Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(AmqpChannelFactoryBean.class); String messageDriven = element.getAttribute("message-driven"); if (StringUtils.hasText(messageDriven)) { builder.addConstructorArgValue(messageDriven); } String connectionFactory = element.getAttribute("connection-factory"); if (!StringUtils.hasText(connectionFactory)) { connectionFactory = "rabbitConnectionFactory"; } builder.addPropertyReference("connectionFactory", connectionFactory); if ("channel".equals(element.getLocalName())) { builder.addPropertyValue("pubSub", false); } else if ("publish-subscribe-channel".equals(element.getLocalName())) { builder.addPropertyValue("pubSub", true); } IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "acknowledge-mode"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "advice-chain"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "amqp-admin"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "channel-transacted"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "concurrent-consumers"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "encoding"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "error-handler"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "exchange"); IntegrationNamespaceUtils.setValueIfAttributeDefined( builder, element, "expose-listener-channel"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converter"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "message-properties-converter"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "phase"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "prefetch-count"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "queue-name"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "receive-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "recovery-interval"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "shutdown-timeout"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "task-executor"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "transaction-attribute"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined( builder, element, "transaction-manager"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "tx-size"); return builder; }
private ManagedMap<String, Object> buildVariablesMap( final Element element, final ParserContext parserContext, List<Element> variableElements) { @SuppressWarnings("serial") ManagedMap<String, Object> variableMap = new ManagedMap<String, Object>() { @Override public Object put(String key, Object value) { if (this.containsKey(key)) { parserContext.getReaderContext().error("Duplicated variable: " + key, element); } return super.put(key, value); } }; for (Element childElement : variableElements) { String variableName = childElement.getAttribute("name"); String variableValue = childElement.getAttribute("value"); String variableRef = childElement.getAttribute("ref"); if (!(StringUtils.hasText(variableValue) ^ StringUtils.hasText(variableRef))) { parserContext .getReaderContext() .error( "Exactly one of the 'ref' attribute or 'value' attribute, " + " is required for element " + IntegrationNamespaceUtils.createElementDescription(element) + ".", element); } if (StringUtils.hasText(variableValue)) { variableMap.put(variableName, variableValue); } else { variableMap.put(variableName, new RuntimeBeanReference(variableRef)); } } String variables = element.getAttribute("variables"); if (StringUtils.hasText(variables)) { String[] variablePairs = StringUtils.commaDelimitedListToStringArray(variables); for (String variablePair : variablePairs) { String[] variableValue = variablePair.split("="); if (variableValue.length != 2) { parserContext .getReaderContext() .error( "Variable declarations in the 'variable' attribute must have the " + "form 'var=value'; found : '" + variablePair + "'", element); } String variable = variableValue[0].trim(); String value = variableValue[1]; if (variable.endsWith("-ref")) { variable = variable.substring(0, variable.indexOf("-ref")); variableMap.put(variable, new RuntimeBeanReference(value)); } else { variableMap.put(variable, value); } } } return variableMap; }
@Override @SuppressWarnings("rawtypes") public BeanDefinition parse(final Element element, ParserContext parserContext) { boolean isNested = parserContext.isNested(); final Map<String, Object> gatewayAttributes = new HashMap<String, Object>(); gatewayAttributes.put("name", element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE)); gatewayAttributes.put( "defaultPayloadExpression", element.getAttribute("default-payload-expression")); gatewayAttributes.put( "defaultRequestChannel", element.getAttribute(isNested ? "request-channel" : "default-request-channel")); gatewayAttributes.put( "defaultReplyChannel", element.getAttribute(isNested ? "reply-channel" : "default-reply-channel")); gatewayAttributes.put("errorChannel", element.getAttribute("error-channel")); gatewayAttributes.put("asyncExecutor", element.getAttribute("async-executor")); gatewayAttributes.put("mapper", element.getAttribute("mapper")); gatewayAttributes.put( "defaultReplyTimeout", element.getAttribute(isNested ? "reply-timeout" : "default-reply-timeout")); gatewayAttributes.put( "defaultRequestTimeout", element.getAttribute(isNested ? "request-timeout" : "default-request-timeout")); List<Element> headerElements = DomUtils.getChildElementsByTagName(element, "default-header"); if (!CollectionUtils.isEmpty(headerElements)) { List<Map<String, Object>> headers = new ArrayList<Map<String, Object>>(headerElements.size()); for (Element e : headerElements) { Map<String, Object> header = new HashMap<String, Object>(); header.put("name", e.getAttribute("name")); header.put("value", e.getAttribute("value")); header.put("expression", e.getAttribute("expression")); headers.add(header); } gatewayAttributes.put("defaultHeaders", headers.toArray(new Map[headers.size()])); } List<Element> methodElements = DomUtils.getChildElementsByTagName(element, "method"); if (!CollectionUtils.isEmpty(methodElements)) { Map<String, BeanDefinition> methodMetadataMap = new ManagedMap<String, BeanDefinition>(); for (Element methodElement : methodElements) { String methodName = methodElement.getAttribute("name"); BeanDefinitionBuilder methodMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(GatewayMethodMetadata.class); methodMetadataBuilder.addPropertyValue( "requestChannelName", methodElement.getAttribute("request-channel")); methodMetadataBuilder.addPropertyValue( "replyChannelName", methodElement.getAttribute("reply-channel")); methodMetadataBuilder.addPropertyValue( "requestTimeout", methodElement.getAttribute("request-timeout")); methodMetadataBuilder.addPropertyValue( "replyTimeout", methodElement.getAttribute("reply-timeout")); boolean hasMapper = StringUtils.hasText(element.getAttribute("mapper")); Assert.state( !hasMapper || !StringUtils.hasText(element.getAttribute("payload-expression")), "'payload-expression' is not allowed when a 'mapper' is provided"); IntegrationNamespaceUtils.setValueIfAttributeDefined( methodMetadataBuilder, methodElement, "payload-expression"); List<Element> invocationHeaders = DomUtils.getChildElementsByTagName(methodElement, "header"); if (!CollectionUtils.isEmpty(invocationHeaders)) { Assert.state(!hasMapper, "header elements are not allowed when a 'mapper' is provided"); Map<String, Object> headerExpressions = new ManagedMap<String, Object>(); for (Element headerElement : invocationHeaders) { BeanDefinition expressionDef = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( "value", "expression", parserContext, headerElement, true); headerExpressions.put(headerElement.getAttribute("name"), expressionDef); } methodMetadataBuilder.addPropertyValue("headerExpressions", headerExpressions); } methodMetadataMap.put(methodName, methodMetadataBuilder.getBeanDefinition()); } 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; } }